命名参数标记允许在运行时将变量值插入 SQL 查询。 不再对特定值进行硬编码,而是在查询运行时定义用户填入的类型占位符。 这可以改进查询重用、防止 SQL 注入,并更轻松地生成灵活的交互式查询。
命名参数标记在以下 Databricks 界面中工作:
- SQL 编辑器(新版和旧版)
- Notebooks
- AI/BI 仪表板数据集编辑器
- Genie 空间
添加命名参数标记
通过输入参数名称(例如 :parameter_name)前加上冒号,来插入参数。 向查询添加命名参数标记时,将显示一个控件,您可以在其中设置参数的类型和值。 请参阅 “使用参数小组件”。
此示例将硬编码查询转换为使用命名参数。
启动查询:
SELECT
trip_distance,
fare_amount
FROM
samples.nyctaxi.trips
WHERE
fare_amount < 5
- 从
5子句中删除WHERE。 - 在其位置键入
:fare_parameter。 最后一行应显示fare_amount < :fare_parameter。 - 单击参数部件旁边的齿轮图标。
- 将 类型 设置为 十进制。
- 在参数小组件中输入值,然后单击“ 应用更改”。
- 单击“保存”。
参数类型
在参数设置面板中设置参数类型。 该类型确定 Databricks 如何在运行时解释和处理值。
| 类型 | 说明 |
|---|---|
| 字符串 | 自由格式文本。 反斜杠、单引号和双引号会被自动转义。 Databricks 在值周围添加引号。 |
| 整数 | 整数值。 |
| 十进制 | 能够支持小数的数值。 |
| 日期 | 日期值。 使用日历选取器,默认为当前日期。 |
| 时间戳 | 日期和时间值。 使用日历选取器,默认为当前日期和时间。 |
命名参数语法示例
以下示例显示了命名参数标记的常见模式。
插入日期
SELECT
o_orderdate AS Date,
o_orderpriority AS Priority,
sum(o_totalprice) AS `Total Price`
FROM
samples.tpch.orders
WHERE
o_orderdate > :date_param
GROUP BY 1, 2
插入数字
SELECT
o_orderdate AS Date,
o_orderpriority AS Priority,
o_totalprice AS Price
FROM
samples.tpch.orders
WHERE
o_totalprice > :num_param
插入字段名称
使用 IDENTIFIER 函数将列名作为参数传递。 参数值应是查询中使用的表中的列名。
SELECT * FROM samples.tpch.orders
WHERE IDENTIFIER(:field_param) < 10000
插入数据库对象
使用具有多个参数的 IDENTIFIER 函数在运行时指定目录、架构和表。
SELECT *
FROM IDENTIFIER(:catalog || '.' || :schema || '.' || :table)
请参阅 IDENTIFIER 条款。
连接多个参数
用于 format_string 将参数合并为单个格式化字符串。 请参阅 format_string函数。
SELECT o_orderkey, o_clerk
FROM samples.tpch.orders
WHERE o_clerk LIKE format_string('%s%s', :title, :emp_number)
使用 JSON 字符串
使用 from_json 函数 通过参数作为键从 JSON 字符串中提取值。 将:param替换为a的值返回1。
SELECT from_json('{"a": 1}', 'map<string, int>') [:param]
创建间隔
使用 CAST 将参数值转换为基于时间计算的 INTERVAL 类型。 请参阅 间隔类型。
SELECT CAST(:param AS INTERVAL MINUTE)
使用.min和.max添加日期范围
日期和时间戳参数支持范围选择器。 使用 .min 和 .max 来访问范围的起始和结束。
SELECT * FROM samples.nyctaxi.trips
WHERE tpep_pickup_datetime
BETWEEN :date_range.min AND :date_range.max
将参数类型设置为 Date 或 Timestamp,并将小组件类型设置为 Range。
使用两个参数添加日期范围
SELECT * FROM samples.nyctaxi.trips
WHERE tpep_pickup_datetime
BETWEEN CAST(:date_range_min AS TIMESTAMP) AND CAST(:date_range_max AS TIMESTAMP)
参数化汇总粒度
请使用 DATE_TRUNC 在用户选择的粒度级别汇总结果。 将DAY、MONTH或YEAR作为参数值。
SELECT
DATE_TRUNC(:date_granularity, tpep_pickup_datetime) AS date_rollup,
COUNT(*) AS total_trips
FROM samples.nyctaxi.trips
GROUP BY date_rollup
将多个值作为字符串传递
使用 ARRAY_CONTAINS、SPLIT 和 TRANSFORM 对传递为单个字符串参数的逗号分隔值列表进行筛选。
SPLIT 将逗号分隔的字符串分析为数组。
TRANSFORM 去除每个元素的空白字符。
ARRAY_CONTAINS 检查表值是否显示在生成的数组中。
SELECT * FROM samples.nyctaxi.trips WHERE
array_contains(
TRANSFORM(SPLIT(:list_parameter, ','), s -> TRIM(s)),
CAST(dropoff_zip AS STRING)
)
注意
此示例适用于字符串值。 若要使用其他数据类型,请用 CAST 封装 TRANSFORM 操作,以将其元素转换为所需类型。
语法迁移参考
将查询从胡须语法转换为命名参数标记时,请使用此表。 有关旧语法的详细信息,请参阅 Mustache 参数语法 。
| 用例 | Mustache 语法 | 命名参数语法 |
|---|---|---|
| 按日期筛选 | WHERE date_field < '{{date_param}}' |
WHERE date_field < :date_param |
| 按数字筛选 | WHERE price < {{max_price}} |
WHERE price < :max_price |
| 比较字符串 | WHERE region = '{{region_param}}' |
WHERE region = :region_param |
| 指定一个表 | SELECT * FROM {{table_name}} |
SELECT * FROM IDENTIFIER(:table) — 使用完整的三级命名空间 |
| 指定目录、架构和表 | SELECT * FROM {{catalog}}.{{schema}}.{{table}} |
SELECT * FROM IDENTIFIER(:catalog \|\| '.' \|\| :schema \|\| '.' \|\| :table) |
| 从多个参数格式化字符串 | "({{area_code}}) {{phone_number}}" |
format_string("(%d) %d", :area_code, :phone_number) |
| 创建间隔 | SELECT INTERVAL {{p}} MINUTE |
SELECT CAST(format_string("INTERVAL '%s' MINUTE", :param) AS INTERVAL MINUTE) |