DeepSeek总结的 DuckDB 2.0 中更简洁的变量语法

DuckDB 2.0 中更简洁的变量语法

2026-10-13 4 分钟阅读

DuckDB 团队

TL;DR: DuckDB 2.0 让你用 $name 引用读取会话变量,而不是调用 getvariable,并且预处理语句在未提供命名参数时可以回退到会话变量。本文展示新语法如何工作,以及这两个特性如何配合。

DuckDB 长期以来通过 SET VARIABLE 语句支持会话变量。你设置一次值,然后在需要的地方读回它,这把一个魔法常量保留在一个地方,而不是分散在脚本各处。到目前为止,读取一个变量意味着调用 getvariable,而这个调用比它背后的想法更冗长。

DuckDB 2.0 增加了一个简写。你可以用 $name 引用读取会话变量,而预处理语句在省略命名参数时可以回退到会话变量。本文走一遍这个特性的两半,并展示它们如何一起工作。

用 $name 读取变量

像你一直做的那样设置变量。

sql 复制代码
SET VARIABLE x = 5;

在 DuckDB 2.0 之前,你用 getvariable 读回它。

sql 复制代码
SELECT getvariable('x') AS x;

在 DuckDB 2.0 中,$x 正是那个调用的简写。

sql 复制代码
SELECT $x AS x;
复制代码
x
5

对于一个已设置的变量,两种形式可以互换。$name 引用解析为该名称会话变量的当前值,所以当 x 设为 5 时,$x 和 getvariable('x') 返回相同结果。

sql 复制代码
SET VARIABLE animal = 'duck';
SELECT $animal = getvariable('animal') AS same;
复制代码
same
true

如果你引用一个未设置的变量,DuckDB 会报错而不是返回 NULL。用 RESET VARIABLE 移除变量后也是如此。

sql 复制代码
RESET VARIABLE animal;
SELECT $animal;
复制代码
Invalid Input Error:
Values were not provided for the following parameters: animal

错误提到参数,是因为 $name 引用和命名预处理语句参数在底层是同一个构造:一个未设置的变量让参数没有值。这种重叠正是让这个特性第二半得以工作的原因。

会话变量作为预处理语句默认值

一个预处理语句声明你在执行它时提供的参数。DuckDB 用同样的 $name 语法命名参数。

sql 复制代码
SET VARIABLE x = 5;
PREPARE double_value AS SELECT $x * 2 AS result;

在执行时提供参数,它就被直接使用。

sql 复制代码
EXECUTE double_value(x := 1);
复制代码
result
2

省略参数,DuckDB 2.0 就回退到同名的会话变量。这里 x 仍然是 5,所以语句计算 5 * 2。

sql 复制代码
EXECUTE double_value;
复制代码
result
10

回退值本身可以来自另一个变量。因为 $y 在被传入之前就解析了,这执行 10 * 2。

sql 复制代码
SET VARIABLE y = 10;
EXECUTE double_value(x := $y);
复制代码
result
20

当一个语句有多个参数时,两个来源自然结合。你提供的每个参数覆盖匹配的变量,你省略的每个参数回退到它。

sql 复制代码
SET VARIABLE multiplier = 10;
SET VARIABLE x = 42;
PREPARE compute AS SELECT $multiplier * $x AS result;

没有参数时,两个参数都来自变量,得到 10 * 42。

sql 复制代码
EXECUTE compute;
复制代码
result
420

覆盖一个参数,另一个仍然回退。EXECUTE compute(multiplier := 3) 计算 3 * 42,而 EXECUTE compute(x := 1) 计算 10 * 1。

语句 结果
EXECUTE compute(multiplier := 3) 126
EXECUTE compute(x := 1) 10
EXECUTE compute(multiplier := 2, x := 5) 10

命名参数和位置参数

回退只适用于命名参数。位置参数,写作 $1、$2 等等,按位置匹配,从不从会话变量填充,即使恰好有一个名为 1 的变量。

如果位置参数没有提供,语句仍然引发缺失参数错误。当你混合两种风格时记住这一点:把你想要从变量默认的参数据命名。

总结

DuckDB 2.0 使会话变量更容易读取,也更容易与预处理语句结合:

  • $name 是 getvariable('name') 的简写,引用未设置的变量会报错。
  • 一个命名预处理语句参数在你没有提供它时回退到同名的会话变量,而显式实参总是胜出。
  • 位置参数只按位置匹配,不回退到变量。

完整参考见 SET VARIABLE 语句和预处理语句页面,两者都列在 DuckDB 的友好 SQL 特性中。

相关推荐
sunshine8852 小时前
集成电路(IC)设计与封测行业10大常用ERP系统分析
大数据·数据库·人工智能
fen_fen2 小时前
Jmeter5.1.1连接oracle数据库的错误复盘
数据库·jmeter·oracle
imDwAaY3 小时前
MySQL 存储引擎是什么?
android·数据库·mysql
星云低代码开发平台3 小时前
ERP 与 CRM 客户信用核对:业务键、时点和权限验收
大数据·数据库·人工智能
xiaogai_gai3 小时前
销售出库单同步实战:旺店通→金蝶云星空的单一策略深度拆解
大数据·前端·数据库
下页、再停留3 小时前
【C#桌面客户端系列学习-11】将SQLite数据库打包到exe里
数据库·c#·visual studio
下页、再停留3 小时前
【C#桌面客户端系列学习-12】封装SQLite数据库基础操作工具类(CURD)
数据库·c#·visual studio
LYmatch3 小时前
2024年408真题第41~47题汇总解析
数据库
程序员Sunday3 小时前
Redis 缓存穿透、击穿、雪崩怎么区分?从回源压力找原因
数据库·redis·缓存