規範是否允許 INSERT 上的列數不匹配?
我只是想知道如果您插入的列少於表提供
INSERT
的列,規範是否允許在語句中排除列列表子句。我看到 PostgreSQL 有,而 MySQL 和 SQL Server 沒有。使用 PostgreSQL,(有效)
# CREATE TABLE t (a int, b int); CREATE TABLE # INSERT INTO t VALUES (42); -- (b is set to DEFAULT) INSERT 0 1
使用 SQL Server,我得到
Msg 213 Level 16 State 1 Line 1 Column name or number of supplied values does not match table definition.
使用 MariaDB,我得到
Column count doesn't match value count at row 1
如果列數不匹配,正確的行為是什麼?
文件草稿可在以下位置找到:
http://www.wiscorp.com/sql20nn.zip
這個問題感興趣的部分是:
7IWD2-02-Foundation-2011-12.pdf
起初,我根本找不到任何關於省略列規範的支持。但是,在 14.11 中,BNF 看起來像:
<insert statement> ::= INSERT INTO <insertion target> <insert columns and source> [...] <insert columns and source> ::= <from subquery> | <from constructor> | <from default> <from subquery> ::= [ <left paren> <insert column list> <right paren> ] [ <override clause> ] <query expression> <from constructor> ::= [ <left paren> <insert column list> <right paren> ] [ <override clause> ] <contextually typed table value constructor> <insert column list> ::= <column name list>
即“列名列表”包含在方括號內,因此可能有也可能沒有列規範。但是,在語法規則下的文本中提到:
7) If the <insert column list> is omitted, then an <insert column list> that identifies all columns of T in the ascending sequence of their ordinal positions within T is implicit.
因此,似乎如果省略列列表,則假定所有列,並且應該從左到右解釋它們。我的猜測是 PostgreSQL 在這方面過於慷慨了。
為了清楚起見,我認為始終聲明列列表是一個好主意(臨時情況除外)。我可以將 Db2 (10.5) 添加到需要部分元組的列列表的產品中:
db2 "INSERT INTO t VALUES (42)" DB21034E The command was processed as an SQL statement because it was not a valid Command Line Processor command. During SQL processing it returned: SQL0117N The number of values assigned is not the same as the number of specified or implied columns or variables. SQLSTATE=42802
我認為 PostgreSQL 違反了規範,Lennart 在他引用的部分是正確的,它也在 SQL:2016 版本中
- 如果 the
<insert column list>
被省略,那麼<insert column list>
在 T 中按其序號位置的升序標識 T 的所有列的 an 是隱含的。但是,再往下走一點,
<query expression>
13) 令 QT 為or指定的表<contextually typed table value constructor>
。QT 的度數應等於 中的<column name>
s數<insert column list>
。表 T 中由第 i 個標識的列<column name>
對應<insert column list>
於 QT 的第 i 個列。因此,
<insert column list>
可以省略,但如果省略,則假定它是整個表格。並且<insert column list>
必須在度數上與<contextually typed table value constructor>
(VALUES
) 相等。正如Marco Borchert在評論中指出的那樣,這實際上在文件中明確表示為“擴展”/違反標準,
第二種形式是 PostgreSQL 擴展。它用給定的盡可能多的值填充左側的列,其餘的將是預設值。