我刚刚遇到一些我认为无效的SQL语法,但实际上工作正常(至少在SQL Server中)。
鉴于此表:
create table SomeTable (FirstColumn int, SecondColumn int)
执行以下insert
语句时没有错误:
insert SomeTable(Any.Text.Here.FirstColumn, It.Does.Not.Matter.What.SecondColumn)
values (1,2);
insert语句完成且没有错误,并且检查select * from SomeTable
表明它确实正确执行。请参阅小提琴:http://sqlfiddle.com/#!6/18de0/2
SQL Server似乎只是忽略除插入列表中给出的列名的最后部分之外的任何内容。
实际问题:
这可以作为记录在案的行为吗?
对于为何如此的任何解释也将不胜感激。
答案 0 :(得分:3)
不太可能成为SQL标准的一部分,因为它具有可疑的效用(尽管我还没有特别检查过(a))。
最可能发生的事情是,它丢弃了列规范的非最终部分,因为它是多余的。您已明确 使用命令的insert into SomeTable
部分说明了您要插入的表格,以及表格中 使用。
您在这里所做的是找到一种方法来执行可读性较差但没有实际优势的SQL命令。在这种情况下,它看起来类似于C代码:
int nine = 9;
int eight = 8;
xyzzy = xyzzy + nine - eight;
或许可以更好地写成xyzzy++;
: - )
我根本不会依赖它,可能因为它不是标准的,但主要是因为它使维护更难而不是更容易,并且因为我知道世界各地的DBA会跟踪我并使用IBM DB2手册将他击败,因为它们的体积和头骨破碎能力使他们选择武器: - )
(a)我非非特意检查,至少是ISO 9075-2:2003,它规定了SQL03语言。
该标准的14.8
部分涵盖insert
声明,似乎以下条款可能相关:
insert-column-list中的每个column-name都应标识T的可更新列。
不花费大量时间(该文件长度为1,332页,需要几天时间才能正确消化),我怀疑你可能会认为只需使用最后一部分即可识别列列名称(通过从中删除所有所有者/用户/架构规范)。
特别是因为它看起来只有一个目标表(尽管有可更新的视图跨越表边界):
<insertion target> ::= <table name>
公平警告:我以后没有检查标准的迭代,所以事情可能已经改变了。但我认为这不太可能,因为似乎没有真正的用例来使用此功能。
答案 1 :(得分:2)
这是关于Connect的reported as a bug,尽管最初鼓励评论,但项目的当前状态已关闭,因为&#34;无法解决&#34;。
Order by子句以类似的方式运行,但在SQL Server 2005中修复了一个。
答案 2 :(得分:1)
当我尝试在SQL Server 2012以及SQL Server 2014和SQL Server 2008 R2上运行脚本时出现错误。所以你当然不能依赖于你用sqlfiddle看到的行为。
即使这样做,我也绝不会依赖生产代码中的无证行为。 Microsoft将包含有关记录功能的更改的通知,但不包括未记录的功能。因此,如果这是一个后来修复的实际T-SQL解析错误,它将破坏格式错误的代码。