如果条件为真,我怎么才能执行更新命令?

时间:2009-08-03 21:05:41

标签: sql sql-server sql-server-2005

我正在处理需要删除列的数据库升级脚本(该部分很容易)。在我删除列之前,我想获取值并将其移动到另一个已存在的列中。

我正试图用我的脚本实现idempotence,这是我似乎失败的地方。我有这样的代码...

IF EXISTS (SELECT * 
         FROM sys.all_columns 
         WHERE sys.all_columns.object_id = OBJECT_ID(N'[dbo].[MyTable]')
         AND sys.all_columns.name = 'Column1')
BEGIN
    UPDATE [dbo].[MyTable] 
    SET [Column2] = [Column1]

    ALTER TABLE [dbo].[MyTable]
    DROP COLUMN [Column1]
END

无论我做什么,始终执行UPDATE查询,即使条件为false,也会导致错误。如果我的初始条件为false,我需要做什么来阻止运行此查询?如果条件为真,它下面的ALTER TABLE语句才会运行。

1 个答案:

答案 0 :(得分:12)

我猜测当你说“UPDATE查询总是被执行,导致错误”时,你的意思是你得到错误:

  

Msg 207, Level 16, State 1 Line 6
      Invalid column name 'Column1'.

这不是因为查询正在执行 - 这是一个解析错误。 SQL Server在执行之前会对整个IF语句进行解析,并且在UPDATE语句中失败,因为Column1不再存在。它在ALTER TABLE语句中也失败了,但SQL Server只显示第一个错误。

顺便说一句,这就是为什么Shannon的例子有效 - 因为她的两个IF块都被立即解析,第二个类似于你的解析就好了,因为在解析脚本时,列仍然存在。我怀疑如果Shannon再次运行她的脚本(减去创建表部分),就会出现同样的错误。

要解决这个问题,您只需要使用动态SQL - 在实际运行该行之前不会对其进行解析。您使用EXEC命令运行动态SQL,并将它传递给您要执行的字符串,如下所示:

IF EXISTS (SELECT * 
         FROM sys.all_columns 
         WHERE sys.all_columns.object_id = OBJECT_ID(N'[dbo].[MyTable]')
         AND sys.all_columns.name = 'Column1')
BEGIN
    EXEC('UPDATE [dbo].[MyTable] SET [Column2] = [Column1]')

    EXEC('ALTER TABLE [dbo].[MyTable] DROP COLUMN [Column1]')
END
相关问题