【问题标题】:Compilation when Column doesn't exist列不存在时的编译
【发布时间】:2016-09-22 23:14:53
【问题描述】:

我有一个如下所示的存储过程:

create procedure test as
begin
if  exists(
               select 1 from sys.columns 
                where Name      = N'Column2'
                  and Object_ID = Object_ID(Table2')
              )

select Column2 from Table2
end

我想在 Column2 不存在的 db 上运行此过程。我不想从 SP 中取出存在检查。目前的错误是:

消息 207,级别 16,状态 1,程序测试,线路 39 [Batch Start Line 0] 列名“Column2”无效。

有什么办法吗?为什么是,为什么不是?

如果您检查存在表并选择有效的不存在表,为什么?

【问题讨论】:

    标签: sql-server tsql stored-procedures


    【解决方案1】:

    使用动态 SQL:

    create procedure test as
    begin
        if exists (select 1
                   from sys.columns 
                   where Name = N'Column2' and Object_ID = Object_ID('Table2')
                  )
        begin
            exec sp_executesql N'select Column2 from Table2';
        end;
    end;
    

    【讨论】:

    • 我从来不知道这是可能的
    • 非常有趣。有谁知道为什么存在检查适用于表而不适用于列?
    • @Sher 这是一个武断的决定——如果你想要背后的事实原因,你必须采访 1990 年代末/2000 年代初 Sybase/SQL Server 团队的成员。
    • @AaronBertrand,这不应该是武断的决定。有些东西一定是不同的,也许列对象是不同的类型。
    • @Sher 他们当时做了很多武断的决定——timestamp(一个令人困惑的类型名称,也违反了 ANSI)、NULL 处理(唯一约束将两个 NULL 视为“相等”——也违反了 ANSI ) 等。我并不是说它应该是一个任意的决定,只是延迟名称解析允许您引用一个不存在的表,而不是一个列,这是一个很久以前做出的决定,我只能说是武断的。是的,列是不同于表的实体类型。
    猜你喜欢
    • 2015-09-06
    • 1970-01-01
    • 2014-01-24
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 2011-05-25
    相关资源
    最近更新 更多