一尘不染

为什么Microsoft SQL Server不检查存储的proc中的列而不检查表?

sql

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对 当前存在的表 中列是否存在的检查?


阅读 103

收藏
2021-03-17

共1个答案

一尘不染

这称为延迟名称解析。

无法关闭它。您可以使用动态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
2021-03-17