Sql-Server

規範是否允許 INSERT 上的列數不匹配?

  • October 28, 2019

我只是想知道如果您插入的列少於表提供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

如果列數不匹配,正確的行為是什麼?

受此問題的回復和評論啟發的問題here

文件草稿可在以下位置找到:

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 版本中

  1. 如果 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 擴展。它用給定的盡可能多的值填充左側的列,其餘的將是預設值。

引用自:https://dba.stackexchange.com/questions/195759