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

Dan*_*ert 3 sql sql-server sql-server-2005

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

我试图用我的剧本来实现幂等,这是我似乎失败的地方.我有这样的代码......

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
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*erg 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
Run Code Online (Sandbox Code Playgroud)