【问题标题】:Firebird/DB2 - referencing column that is declared laterFirebird/DB2 - 稍后声明的引用列
【发布时间】:2019-08-10 11:34:48
【问题描述】:

假设我们有一些简单的代码,例如:

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
);

元数据更新不成功 CREATE TABLE TAB 失败 动态 SQL 错误 SQL 错误代码 = -206 列未知 ID

或:

[IBM][CLI Driver][DB2/LINUXX8664] SQL0205N 列、属性或句点“ID”未在“FIDDLE_QSNXRANMEEPHZPWEWQDV.TAB”中定义。 SQLSTATE=42703 SQLCODE=-205

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,说明在同一级别定义条目的特定顺序是否是强制性的。

【问题讨论】:

  • 那么,问题是......?
  • @BarbarosÖzhan 问题是这种行为是否符合标准。
  • @LukashSzozda 。 . .我很惊讶在尚未定义的列上定义约束适用于任何数据库。我什至不会考虑以这种方式编写 SQL。我想该标准对这个特定主题没有太多要说的;它可能相当模棱两可。
  • 据我所知,快速浏览一下,SQL 标准 (ISO/IEC 9075-2:2016) 没有说明任何内容。 11.3 中的措辞不够具体,无法明确说明是否允许,甚至是否需要。
  • CREATE TABLE comments( comment_id INT REFERENCES comments(id), - 在 Firebird 上创建自引用表很危险,可能导致服务器崩溃。保持警惕。

标签: sql db2 firebird create-table


【解决方案1】:

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

SQL 标准没有规定指定&lt;column definition&gt;s 和&lt;constraint definition&gt; 的顺序;它1确实这样说,但是,关于句法规则的评估顺序(强调原文):

如果优先级不是由格式或括号确定的,则表达式的有效评估 一般是从左到右进行的。但是,表达式是否为 实际上从左到右评估,特别是当操作数或运算符可能导致条件被引发或 如果可以在不完全评估表达式的所有部分的情况下确定表达式的结果。

换句话说,标准让实现来决定它是按照指定的顺序处理表定义子句,还是先处理&lt;column definition&gt;s,然后再处理&lt;constraint definition&gt;s。

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


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

【讨论】:

  • 好点,尽管表达式与表定义不同。我不确定您引用的规则是否适用于此。
  • 感谢发布。看起来更接近于找到一个明确的答案。如果引用相关的“表达式”与约束/列相同,我也有点不相信。尽管如此,这是一个线索,我可以猜测它“类比”的工作原理相同。
  • 这些是 syntax 规则,适用于任何 SQL 语句的语法评估。
  • @mustaccio 但是,引用与表达式的评估顺序和优先级有关,CREATE TABLE 不是表达式,CREATE TABLE 中的定义也不是。也就是说,重读 11.3 ,它确实说 - 释义 - 创建表会导致一组列定义和一组表约束定义,并且在该视图中,您可以争辩列定义之间的顺序和表约束定义不相关,因为它们是单独的集合。
  • 根据您上面的表述,您对“表达式”一词的解释似乎只包括值表达式,而我引用的段落谈到了适用的句法、访问和一般规则的评估顺序标准定义的所有声明。
【解决方案2】:

据我所知,快速浏览一下,SQL 标准 (ISO/IEC 9075-2:2016) 没有说明任何内容。 11.3

中的措辞不够具体,无法明确说明是否允许,甚至是否需要。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 2018-11-06
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多