存在测试列,添加列和更新列

Dav*_*rke 49 t-sql sql-server ddl

我正在尝试编写SQL Server数据库更新脚本.我想测试表中是否存在列,然后如果它不存在则添加具有默认值的列,最后根据同一表中不同列的当前值更新该列.我希望这个脚本可以多次运行,第一次更新表时,在后续运行中应该忽略脚本.我的脚本目前如下所示:

IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'PurchaseOrder' AND COLUMN_NAME = 'IsDownloadable')
BEGIN

ALTER TABLE [dbo].[PurchaseOrder] ADD [IsDownloadable] bit NOT NULL DEFAULT 0

UPDATE [dbo].[PurchaseOrder] SET [IsDownloadable] = 1 WHERE [Ref] IS NOT NULL

END
Run Code Online (Sandbox Code Playgroud)

SQL Server返回错误"无效的列名'IsDownloadable'",即我需要在更新列之前提交DDL.我尝试了各种排列,但是我无法快速进行.

Aar*_*ght 81

除非该列已经存在,这是什么时候你该脚本将不能成功运行并不需要它.

必须先解析SQL脚本,然后才能执行它们.如果在解析脚本时该列不存在,则解析将失败.您的脚本稍后创建列并不重要; 解析器无法知道这一点.

GO如果要访问刚刚添加的列,则需要输入语句(批处理分隔符).但是,一旦执行此操作,您就无法再保留上一批中的任何控制流或变量 - 就像运行两个单独的脚本一样.这使得同时有条件地同时执行DDL和DML变得棘手.

最简单的解决方法,我可能推荐给你,因为你的DML不是很复杂,是使用动态SQL,解析器在"运行时"之前不会尝试解析:

IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'PurchaseOrder' AND COLUMN_NAME = 'IsDownloadable')
BEGIN

    ALTER TABLE [dbo].[PurchaseOrder] ADD 
        [IsDownloadable] bit NOT NULL DEFAULT 0

    EXEC sp_executesql
        N'UPDATE [dbo].[PurchaseOrder] SET [IsDownloadable] = 1 WHERE [Ref] IS NOT NULL'

END
Run Code Online (Sandbox Code Playgroud)