Firebird / DB2-稍后声明的引用列

时间:2019-08-10 11:34:48

标签: sql db2 firebird create-table

假设我们有一些琐碎的代码,例如:

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>

db<>fiddle demo - Firebird

db<>fiddle demo - DB2

任何其他主要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
);

db<>fiddle demo - FK

例如,存在引用不存在的对象的想法: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,该文档说明是否必须在同一级别上定义条目的特定顺序。

2 个答案:

答案 0 :(得分:3)

有人可能会说Db2和Firebase表现出的行为更符合SQL的声明性。 SQL是其中之一的强类型语言通常不允许使用未声明的标识符。

SQL标准没有规定任何顺序来指定<column definition><constraint definition>;但是,就句法规则的评估顺序(强调原语)而言,它是 1 这样做

  

如果优先级不受格式或括号的影响,则表达式的有效求值   通常是从左到右执行。但是,表达式是否与实现有关。   实际上从左到右评估,尤其是当操作数或运算符可能导致条件升高或   是否可以在不完全评估表达式所有部分的情况下确定表达式的结果。

换句话说,该标准将其留给实现来决定是按表定义子句的指定顺序处理它们,还是先处理<column definition>,再处理<constraint definition>。 / p>

来源:ISO/IEC 9075-1ISO/IEC 9075-2的规范草案。


1-ISO / IEC 9075-1,第6.3.3.3段规则评估顺序

答案 1 :(得分:2)

据我所知,SQL标准(ISO / IEC 9075-2:2016)对此没有任何说明。 11.3 <表定义>中的措词不够具体,无法确切地说出是否允许,甚至是必需。