DuckDB 有特殊的字面量类型,用于在查询中表示 NULL、整数和字符串字面量。这些类型有自己的绑定和转换规则。
在DuckDB版本0.10.0之前,整数和字符串字面量的行为与
INTEGER和VARCHAR类型相同。
空字面量
NULL 字面量用关键字 NULL 表示。NULL 字面量可以隐式转换为任何其他类型。
整数字面量
整数字面量表示为一个或多个数字的序列。在运行时,这些字面量会产生INTEGER_LITERAL类型的值。INTEGER_LITERAL类型可以隐式转换为任何整数类型,只要值适合该类型。例如,整数字面量42可以隐式转换为TINYINT,但整数字面量1000则不能。
其他数字字面量
非整数数字字面量可以用十进制表示法表示,使用句点字符(.)来分隔数字的整数部分和小数部分。
整数部分或小数部分可以省略:
SELECT 1.5; -- 1.5
SELECT .50; -- 0.5
SELECT 2.; -- 2.0
非整数数字字面量也可以使用E表示法来表示。在E表示法中,一个整数或十进制字面量后面跟着一个指数部分,该部分由e或E表示,后面跟着一个表示指数的整数。
指数部分表示前面的值应乘以10的指数次方:
SELECT 1e2; -- 100
SELECT 6.02214e23; -- Avogadro's constant
SELECT 1e-10; -- 1 ångström
数字字面量中的下划线
DuckDB的SQL方言允许在数字字面量中使用下划线字符_作为可选的分隔符。使用下划线的规则如下:
- 整数、十进制、十六进制和二进制表示法中允许使用下划线。
- 下划线不能是字面量中的第一个或最后一个字符。
- 下划线必须在它们的任一侧有一个整数/数字部分,即不能在一行中有多个下划线,也不能紧接在小数或指数之前/之后。
示例:
SELECT 100_000_000; -- 100000000
SELECT '0xFF_FF'::INTEGER; -- 65535
SELECT 1_2.1_2E0_1; -- 121.2
SELECT '0b0_1_0_1'::INTEGER; -- 5
字符串字面量
字符串字面量使用单引号(',撇号)分隔,并生成STRING_LITERAL值。
请注意,双引号(")不能用作字符串分隔符:相反,双引号用于分隔引用标识符。
隐式字符串字面量连接
仅由包含至少一个换行符的空白分隔的连续单引号字符串字面量会被隐式连接:
SELECT 'Hello'
' '
'World' AS greeting;
等同于:
SELECT 'Hello'
|| ' '
|| 'World' AS greeting;
它们都返回以下结果:
| 问候 |
|---|
| 你好,世界 |
请注意,隐式连接仅在字面量之间至少有一个换行符时才有效。使用由空格分隔且没有换行符的相邻字符串字面量会导致语法错误:
SELECT 'Hello' ' ' 'World' AS greeting;
Parser Error: syntax error at or near "' '"
LINE 1: SELECT 'Hello' ' ' 'World' AS greeting;
^
还要注意,隐式连接仅适用于单引号字符串字面量,不适用于其他类型的字符串值。
隐式字符串转换
STRING_LITERAL 实例可以隐式转换为任何其他类型。
例如,我们可以将字符串字面量与日期进行比较:
SELECT d > '1992-01-01' AS result FROM (VALUES (DATE '1992-01-01')) t(d);
| 结果 |
|---|
| false |
然而,我们不能将VARCHAR值与日期进行比较。
SELECT d > '1992-01-01'::VARCHAR FROM (VALUES (DATE '1992-01-01')) t(d);
Binder Error: Cannot compare values of type DATE and type VARCHAR - an explicit cast is required
转义字符串字面量
要在字符串字面量中转义单引号(撇号)字符,请使用''。例如,SELECT '''' AS s返回'。
要包含特殊字符(如换行符),请使用E对字符串进行转义。大写(E'...')和小写变体(e'...')都有效。
SELECT E'Hello\nworld' AS msg;
或者:
SELECT e'Hello\nworld' AS msg;
┌──────────────┐
│ msg │
│ varchar │
├──────────────┤
│ Hello\nworld │
└──────────────┘
支持以下反斜杠转义序列:
| 转义序列 | 名称 | ASCII 码 |
|---|---|---|
\b |
退格 | 8 |
\f |
换页 | 12 |
\n |
换行 | 10 |
\r |
回车 | 13 |
\t |
制表符 | 9 |
美元引号字符串字面量
DuckDB 支持使用双美元符号($$)包围的美元引号字符串字面量:
SELECT $$Hello
world$$ AS msg;
┌──────────────┐
│ msg │
│ varchar │
├──────────────┤
│ Hello\nworld │
└──────────────┘
SELECT $$The price is $9.95$$ AS msg;
| 消息 |
|---|
| 价格是$9.95 |
隐式连接仅适用于单引号字符串字面量,不适用于美元引号字符串。