Firebird/DB2 - 引用稍后声明的列
Firebird/DB2 - referencing column that is declared later
假设我们有像这样的简单代码:
CREATE TABLE tab(
id INT NOT NULL PRIMARY KEY,
CONSTRAINT greater_than_10 CHECK (id > 10)
);
定义了具有单列和约束的 table。现在,如果我们切换顺序:
CREATE TABLE tab(
CONSTRAINT greater_than_10 CHECK (id > 10),
id INT NOT NULL PRIMARY KEY
);
unsuccessful metadata update CREATE TABLE TAB failed Dynamic SQL Error SQL error code = -206 Column unknown ID
或:
[IBM][CLI Driver][DB2/LINUXX8664] SQL0205N Column, attribute, or period "ID" is not defined in "FIDDLE_QSNXRANMEEPHZPWEWQDV.TAB". SQLSTATE=42703 SQLCODE=-205
此行为在任何其他主要 RDBMS 中都不存在:
db<>fiddle demo - Oracle -
db<>fiddle demo - SQL Server -
db<>fiddle demo - PostgreSQL
编辑:
它也适用于引用相同的外键table:
-- here I could define columns in any order, neat feature
CREATE TABLE comments(
comment_id INT REFERENCES comments(id),
id INT PRIMARY KEY
);
存在引用不存在的对象的想法,例如:T-SQL 存储过程延迟名称解析或 C/C++ 前向声明。
编辑 2:
此行为甚至适用于计算列:
-- SQL Server
CREATE TABLE t(
col AS (id + 1),
id INT
);
-- PostgreSQL 12
CREATE TABLE t(
col INT GENERATED ALWAYS AS (id + 1) STORED,
id INT
);
-- Oracle/MySQL 8.0/MariaDB 10.4
CREATE TABLE t(
col INT AS (id + 1),
id INT
);
正在搜索官方 documentation/ISO 说明在同一级别定义条目的特定顺序是否是强制性的。
据我所知,快速浏览一下,SQL 标准 (ISO/IEC 9075-2:2016) 对此没有任何说明。 11.3
中的措辞不够具体,无法明确说明是否允许,甚至是必需的。
有人可能会争辩说 Db2 和 Firebase 表现出的行为更符合 SQL 的声明性质。强类型语言(SQL 就是其中之一)通常不允许使用未声明的标识符。
SQL标准没有规定任何指定<column definition>
s和<constraint definition>
的顺序; it1确实这样说,但是,关于句法规则的求值顺序(强调原文):
Where the precedence is not determined by the Formats or by parentheses, effective evaluation of expressions
is generally performed from left to right. However, it is implementation-dependent whether expressions are
actually evaluated left to right, particularly when operands or operators might cause conditions to be raised or
if the results of the expressions can be determined without completely evaluating all parts of the expression.
换句话说,标准让实现来决定它是按照指定的顺序处理 table 定义子句,还是先处理 <column definition>
和 [=11] =]秒后。
来源:ISO/IEC 9075-1 and ISO/IEC 9075-2.
的规范草案
1 - ISO/IEC 9075-1,第 6.3.3.3 段 规则评估顺序。
假设我们有像这样的简单代码:
CREATE TABLE tab(
id INT NOT NULL PRIMARY KEY,
CONSTRAINT greater_than_10 CHECK (id > 10)
);
定义了具有单列和约束的 table。现在,如果我们切换顺序:
CREATE TABLE tab(
CONSTRAINT greater_than_10 CHECK (id > 10),
id INT NOT NULL PRIMARY KEY
);
unsuccessful metadata update CREATE TABLE TAB failed Dynamic SQL Error SQL error code = -206 Column unknown ID
或:
[IBM][CLI Driver][DB2/LINUXX8664] SQL0205N Column, attribute, or period "ID" is not defined in "FIDDLE_QSNXRANMEEPHZPWEWQDV.TAB". SQLSTATE=42703 SQLCODE=-205
此行为在任何其他主要 RDBMS 中都不存在:
db<>fiddle demo - Oracle - db<>fiddle demo - SQL Server - db<>fiddle demo - PostgreSQL
编辑:
它也适用于引用相同的外键table:
-- here I could define columns in any order, neat feature
CREATE TABLE comments(
comment_id INT REFERENCES comments(id),
id INT PRIMARY KEY
);
存在引用不存在的对象的想法,例如:T-SQL 存储过程延迟名称解析或 C/C++ 前向声明。
编辑 2:
此行为甚至适用于计算列:
-- SQL Server
CREATE TABLE t(
col AS (id + 1),
id INT
);
-- PostgreSQL 12
CREATE TABLE t(
col INT GENERATED ALWAYS AS (id + 1) STORED,
id INT
);
-- Oracle/MySQL 8.0/MariaDB 10.4
CREATE TABLE t(
col INT AS (id + 1),
id INT
);
正在搜索官方 documentation/ISO 说明在同一级别定义条目的特定顺序是否是强制性的。
据我所知,快速浏览一下,SQL 标准 (ISO/IEC 9075-2:2016) 对此没有任何说明。 11.3