Microsoft SQL Server似乎在定义存储过程时检查列名的有效性,但不检查表名的有效性。如果检测到当前存在被引用的表名,则会针对该表中的列验证语句中的列名。因此,例如,这将运行正常:
CREATE PROCEDURE [dbo].[MyProcedure] AS BEGIN SELECT Col1, Col2, Col3 FROM NonExistentTable END GO
…就像这样:
CREATE PROCEDURE [dbo].[MyProcedure] AS BEGIN SELECT ExistentCol1, ExistentCol2, ExistentCol3 FROM ExistentTable END GO
…但是失败,带有“无效的列名”:
CREATE PROCEDURE [dbo].[MyProcedure] AS BEGIN SELECT NonExistentCol1, NonExistentCol2, NonExistentCol3 FROM ExistentTable END GO
为什么SQL Server会检查列(而不是表)是否存在?肯定是不一致的;它应该两者都做,或者两者都不做。对于我们来说,能够定义可能引用表中尚不存在的表和/或列的SP很有用,因此有没有办法关闭SQL Server对 当前存在的表 中列是否存在的检查?
这称为延迟名称解析。
无法关闭它。您可以使用动态SQL或(讨厌的技巧!)添加对不存在的表的引用,以便推迟对该语句的编译。
CREATE PROCEDURE [dbo].[MyProcedure] AS BEGIN CREATE TABLE #Dummy (c int) SELECT NonExistantCol1, NonExistantCol2, NonExistantCol3 FROM ExistantTable WHERE NOT EXISTS(SELECT * FROM #Dummy) DROP TABLE #Dummy END GO