SQL 标准每隔几年就会发布一次,最新的 SQL:2023 已经编写完成,预计很快就会发布。
本文给大家简单介绍一下最新标准中的型特性,主要分为以下三大类别:
- 已有 SQL 语言的增强;
- JSON 相关的新特性;
- 新增的属性图查询语言。
该版本新增功能都属于可选特性。
SQL 增强
UNIQUE 约束中的空值(F292)
这个功能用于定义唯一约束中是否允许多个空值。例如:
CREATE TABLE t1 (
a int,
b int,
c int,
UNIQUE (a, b, c)
);
INSERT INTO t1 VALUES (1, NULL, NULL);
INSERT INTO t1 VALUES (1, NULL, NULL); -- ?
问题在于第二个插入语句是否会违法唯一约束。
显然,已有的标准没有明确的定义。为了解决这个问题,新标准增加了一个选项。例如:
CREATE TABLE t2 (
a int,
b int,
c int,
UNIQUE NULLS DISTINCT (a, b, c)
);
INSERT INTO t2 VALUES (1, NULL, NULL);
INSERT INTO t2 VALUES (1, NULL, NULL); -- 正确
同时,
CREATE TABLE t3 (
a int,
b int,
c int,
UNIQUE NULLS NOT DISTINCT (a, b, c)
);
INSERT INTO t3 VALUES (1, NULL, NULL);
INSERT INTO t3 VALUES (1, NULL, NULL); -- 错误
NULLS DISTINCT 选项将多个空值看作不同的数据,因此不会违反唯一约束;NULLS NOT DISTINCT 选项将多个空值看作相同的数据,因此违反了唯一约束。
该选项的默认值取决于数据库产品的具体实现,这样可以兼容已有的行为。
分组表中的 ORDER BY(F868)
我们来看一个示例:
CREATE TABLE product (
product_id int PRIMARY KEY,
product_name varchar,
product_code varchar UNIQUE
);
CREATE TABLE product_part (
product_id int,
part_id int,
num int,
PRIMARY KEY (product_id, part_id)
);
SELECT product.product_id, sum(product_part.num)
FROM product JOIN product_part ON product.product_id = product_part.product_id
GROUP BY product.product_id
ORDER BY product.product_code;
以上示例在大多数 SQL 实现中都能正常工作,但是标准却不允许这种查询方式。也就是说,SQL 标准不允许使用没有出现在 SELECT 列表中的分组表字段(product.product_code)进行排序。新标准则允许 SQL 实现明确支持这种行为。
作为用户,我们并不需要关心这个问题。
GREATEST 和 LEAST 函数(T054)
这个功能增加了两个新的标量函数:GREATEST(最大值)以及 LEAST(最小值)。它们不是聚合函数 MAX 和 MIN,而是返回一组参数中的最大值和最小值。实际上很多数据库已经实现了这两个函数:
SELECT greatest(1, 2); --> 2
SELECT least(1, 2); --> 1
SELECT greatest(1, 2, 3); --> 3
SELECT least(1, 2, 3); --> 1
字符串填充函数(T055)
这个功能增加了两个新的字符串函数:LPAD(左侧填充)以及 RPAD(右侧填充)。这两个函数同样在很多数据库中已经有了实现:
SELECT lpad(cast(12345.67 as varchar), 12, '*');
****12345.67
默认使用的填充字符为空格。
多字符 TRIM 函数(T056)
已有的单字符截断函数(TRIM({LEADING|TRAILING|BOTH} ‘x’ FROM val))只能指定要截断的单个字符,新函数则可以指定多个需要截断的字符,而且语法更加简洁。例如:
SELECT ltrim('****12345.67', '*');
可选的字符串类型最大长度(T081)
这个功能允许不指定 VARCHAR 类型的最大长度。在此之前,我们经常会看到为了支持任意长度而指定一个很大的长度值:
CREATE TABLE t1 (
a VARCHAR(1000),
b VARCHAR(4000),
...
);
现在可以简单的指定数据类型:
CREATE TABLE t1 (
a VARCHAR,
b VARCHAR,
...
);
这种情况下,字段的最大长度取决于数据库实现。
增强的递归循环标识(T133)
CYCLE 子句是鲜为人知的一个递归查询功能,可以用于检测循环递归:
WITH RECURSIVE ... (
SELECT ...
UNION ALL
SELECT ...
)
CYCLE id SET is_cycle TO 'Y' DEFAULT 'N' USING path;
这种方式可以基于 id 字段检测是否出现循环递归,并且将 is_cycle 字段设置为指定值。
当 SQL 标准增加递归循环时,还没有布尔类型,因此使用了一个字符串。如今 SQL 标准提供了布尔类型,因此上面的查询可以改进为:
WITH RECURSIVE ... (
SELECT ...
UNION ALL
SELECT ...
)
CYCLE id SET is_cycle USING path;
ANY_VALUE 函数(T626)
这个新的聚合函数可以从一组数据中返回任意一个非空值。例如:
CREATE TABLE t1 (
a int,
b int
);
INSERT INTO t1 VALUES (1, 11), (1, 22), (1, 33);
SELECT a, any_value(b)
FROM t1
GROUP BY a;
以上查询可能会返回(1 | 11)、(1 | 22)或者(1 | 33)。
非十进制的整数常量(T661)
这个新功能支持十六进制、八进制以及二进制的整数常量。
SELECT 0xFFFF, 0o755, 0b11001111;
数字常量中的下划线(T662)
这个功能允许在数字常量中使用下划线,提高可读性。
SELECT ... WHERE a > 1_000_000;
UPDATE ... SET x = 0x_FFFF_FFFF ...
JSON 新功能
JSON 数据类型(T801)
新标准增加了 JSON 数据类型。许多数据库产品实际上已经提供了这个类型。
SQL:2016 只是支持了 JSON 数据的操作,数据仍然使用字符串存储。新的功能同时还增加了一些 JSON 相关的函数,例如 JSON_SERIALIZE、JSON_SCALAR 以及 IS JSON。
增强的 JSON 数据类型(T802)
这个功能可以为 JSON 类型指定额外的选项。具体来说,可以指定一个唯一键检测,例如 JSON(‘…text…’ WITH UNIQUE KEYS)。
基于字符串的 JSON(T803)
这个功能代表了 SQL:2016 中的字符串 JSON。数据库提供的 JSON 函数(例如 JSON_OBJECT、JSON_OBJECTAGG、JSON_TABLE 等)可以选择支持字符串格式的 JSON 数据还是原生的 JSON 数据类型,也可以支持两者。
SQL/JSON 路径中的十六进制整数常量(T840)
这个功能允许在 SQL/JSON 路径语言中使用十六进制整数常量。
虽然不属于这个功能,但是 SQL 标准现在允许以扩展插件的形式支持 JavaScript(ECMAScript),因此不需要每次 ECMAScript 更新时更新 SQL 标准。所以 SQL/JSON 路径现在也可以支持最新 ECMAScript 中的其他数字常量,例如二进制整数和下划线分隔符。
SQL/JSON 简化访问符(T860-T864)
“简化访问符”功能允许使用点号和数组语法访问 JSON 数据中的复合类型和数组类型。例如,假设字段 j 是一个 JSON 类型,包含以下数据:
{"foo": {"bar": [100, 200, 300]}, ...}
我们可以使用简化访问符获取字段中的信息:
SELECT t.j.foo.bar[2], ...
FROM tbl t ...
SQL/JSON 元素方法(T865-T878)
SQL/JSON 元素方法或者函数可以在 SQL/JSON 路径表达式中使用,对元素值进行处理。SQL:2016 已经定义了一些这类方法,例如 abs()、floor()、size()。新增的方法主要用于数据类型转换:
- T865: SQL/JSON item method: bigint()
- T866: SQL/JSON item method: boolean()
- T867: SQL/JSON item method: date()
- T868: SQL/JSON item method: decimal()
- T869: SQL/JSON item method: decimal() with precision and scale
- T870: SQL/JSON item method: integer()
- T871: SQL/JSON item method: number()
- T872: SQL/JSON item method: string()
- T873: SQL/JSON item method: time()
- T874: SQL/JSON item method: time_tz()
- T875: SQL/JSON item method: time precision
- T876: SQL/JSON item method: timestamp()
- T877: SQL/JSON item method: timestamp_tz()
- T878: SQL/JSON item method: timestamp precision
JSON 数据比较功能(T879-T882)
这个功能允许针对 JSON 数据类型的比较、排序以及分组操作。
属性图查询语言
这是 SQL 标准中增加的一个全新部分:Property Graph Queries (SQL/PGQ)。这个新功能支持使用图数据库的方式查询表中的数据。
完整的属性图查询语言比较复杂,以下是一个简单的示例:文章来源:https://www.toymoban.com/news/detail-439071.html
CREATE TABLE person (...);
CREATE TABLE company (...);
CREATE TABLE ownerof (...);
CREATE TABLE transaction (...);
CREATE TABLE account (...);
CREATE PROPERTY GRAPH financial_transactions
VERTEX TABLES (person, company, account)
EDGE TABLES (ownerof, transaction);
SELECT owner_name,
SUM(amount) AS total_transacted
FROM financial_transactions GRAPH_TABLE (
MATCH (p:person WHERE p.name = 'Alice')
-[:ownerof]-> (:account)
-[t:transaction]- (:account)
<-[:ownerof]- (owner:person|company)
COLUMNS (owner.name AS owner_name, t.amount AS amount)
) AS ft
GROUP BY owner_name;
以上示例中,表之间还需要定义外键,这样属性图定义才能确定它们之间的联系;或者也可以在属性图定义时指定表之间的联系。文章来源地址https://www.toymoban.com/news/detail-439071.html
到了这里,关于最新标准SQL:2023新特性预览的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!