假设我们有一些琐碎的代码,例如:
CREATE TABLE tab(
id INT NOT NULL PRIMARY KEY,
CONSTRAINT greater_than_10 CHECK (id > 10)
);
定义了具有单列和约束的表。现在,如果我们切换顺序:
CREATE TABLE tab(
CONSTRAINT greater_than_10 CHECK (id > 10),
id INT NOT NULL PRIMARY KEY
);
元数据更新失败创建表选项卡失败动态SQL错误SQL错误代码= -206 列未知ID
或:
[IBM] [CLI驱动程序] [DB2 / LINUXX8664] SQL0205N 在“ FIDDLE_QSNXRANMEEPHZPWEWQDV.TAB”中未定义列,属性或期间“ ID”。 SQLSTATE = 42703 SQLCODE = -205 < / p>
任何其他主要RDBMS中都不存在此行为:
db<>fiddle demo - Oracle- db<>fiddle demo - SQL Server- db<>fiddle demo - PostgreSQL
编辑:
它也适用于引用同一表的外键:
-- 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
);
搜索官方文档/ ISO,该文档说明是否必须在同一级别上定义条目的特定顺序。
答案 0 :(得分:3)
有人可能会说Db2和Firebase表现出的行为更符合SQL的声明性。 SQL是其中之一的强类型语言通常不允许使用未声明的标识符。
SQL标准没有规定任何顺序来指定<column definition>
和<constraint definition>
;但是,就句法规则的评估顺序(强调原语)而言,它是 1 这样做:
如果优先级不受格式或括号的影响,则表达式的有效求值 通常是从左到右执行。但是,表达式是否与实现有关。 实际上从左到右评估,尤其是当操作数或运算符可能导致条件升高或 是否可以在不完全评估表达式所有部分的情况下确定表达式的结果。
换句话说,该标准将其留给实现来决定是按表定义子句的指定顺序处理它们,还是先处理<column definition>
,再处理<constraint definition>
。 / p>
来源:ISO/IEC 9075-1和ISO/IEC 9075-2的规范草案。
1-ISO / IEC 9075-1,第6.3.3.3段规则评估顺序。
答案 1 :(得分:2)
据我所知,SQL标准(ISO / IEC 9075-2:2016)对此没有任何说明。 11.3 <表定义>中的措词不够具体,无法确切地说出是否允许,甚至是必需。