即使条件不为真,T-Sql似乎也在评估“If”语句

时间:2013-11-06 21:08:45

标签: sql-server tsql if-statement

我有一个T-Sql脚本,其中部分脚本会检查a表中是否存在某个列。如果是这样,我希望它执行例程......如果没有,我希望它绕过这个例程。我的代码如下所示:

IF COL_LENGTH('Database_Name.dbo.Table_Name', 'Column_Name1') IS NOT NULL
    BEGIN
        UPDATE Table_Name
            SET Column_Name2 = (SELECT Column_Name3 FROM Table_Name2
                WHERE Column_Name4 = 'Some Value')
            WHERE Column_Name5 IS NULL;

        UPDATE Table_Name
            SET Column_Name6 = Column_Name1
            WHERE Column_Name6 IS NULL;
    END

我的问题是,即使Column_Name1的COL_LENGTH为空(意味着它不存在),我仍然会在IF语句的第二个UPDATE语句中收到错误告诉我“无效的列名'Column_Name1'”。由于某种原因,即使条件为FALSE且我不知道原因,这个IF条件仍在评估中。

2 个答案:

答案 0 :(得分:11)

SQL Server解析该语句并对其进行验证,忽略任何if条件。这就是为什么以下内容也失败了:

IF 1 = 1
BEGIN
  CREATE TABLE #foo(id INT);
END
ELSE
BEGIN
  CREATE TABLE #foo(id INT);
END

无论是点击执行还是仅解析,都会导致:

  

Msg 2714,Level 16,State 1   
数据库中已经有一个名为'#foo'的对象。

SQL Server不知道或关心条件的哪个分支将被输入;它无论如何都会验证批处理中的所有语句。您可以执行以下操作(由于延迟名称解析):

IF <something>
BEGIN
  SELECT foo FROM dbo.Table_That_Does_Not_Exist;
END

但你不能这样做:

IF <something>
BEGIN
  SELECT column_that_does_not_exist FROM dbo.Table_That_Does;
END

解决方法通常是使用动态SQL:

IF <something>
BEGIN
  DECLARE @sql NVARCHAR(MAX);
  SET @sql = N'SELECT column_that_does_not_exist FROM dbo.Table_That_Does;';
  EXEC sp_executesql @sql;
END

答案 1 :(得分:2)

使你的陈述成为一个字符串。如果列存在,则执行它

IF COL_LENGTH('Database_Name.dbo.Table_Name', 'Column_Name1') IS NOT NULL
BEGIN
    DECLARE @sql VARCHAR(MAX)
    SET @sql = 'UPDATE Table_Name
            SET Column_Name2 = (SELECT Column_Name3 FROM Table_Name2
                WHERE Column_Name4 = ''Some Value'')
            WHERE Column_Name5 IS NULL;

        UPDATE Table_Name
            SET Column_Name6 = Column_Name1
            WHERE Column_Name6 IS NULL;'
     EXEC(@sql)
END