【问题标题】:Make a SQL Server script compile including a column that doesn't exist?编译包含不存在的列的 SQL Server 脚本?
【发布时间】:2020-07-30 19:35:03
【问题描述】:

我有一个 SQL 脚本,它在删除列之前作为数据库迁移运行。它第一次运行良好,因为源列存在,但如果您尝试再次运行迁移它会失败,因为现在该列不存在。我将它包装在一个 IF 中,因此该语句仅在该列确实存在时运行,但它仍然需要能够编译该位,即使我知道它不会运行它。

这是一个简化版:

IF COL_LENGTH('TableA', 'SourceColumn') IS NOT NULL
BEGIN
    UPDATE TableB
    SET DestColumn = TableA.SourceColumn
    FROM TableB
    JOIN TableA AS ON TableB.AId = TableA.Id
    WHERE TableB.DestColumn != TableA.SourceColumn;
END

ALTER TABLE TableA 
DROP COLUMN SourceColumn;

【问题讨论】:

  • exec('UPDATE TableB ......WHERE TableB.DestColumn != TableA.SourceColumn;');

标签: sql sql-server


【解决方案1】:

一种方法是动态SQL:

IF COL_LENGTH('TableA', 'SourceColumn') IS NOT NULL
BEGIN
    DECLARE @sql NVARCHAR(MAX);

    SET @sql = '
UPDATE TableB
    SET DestColumn = TableA.SourceColumn
FROM TableB JOIN
     TableA 
     ON TableB.AId = TableA.Id
WHERE TableB.DestColumn <> TableA.SourceColumn';

    EXEC sp_executesql @sql;
END;

您也可以使用有趣的技巧来解决这个问题,而不是使用动态 SQL。 . .假设 id 是主键:

IF COL_LENGTH('TableA', 'SourceColumn') IS NOT NULL
BEGIN
    UPDATE TableB
    SET DestColumn = a.SourceColumn
    FROM TableB JOIN
         (SELECT a.id,
                 (SELECT SourceColumn   -- NO ALIAS!!
                  FROM TableA a2
                  WHERE a2.id = a.id
                 ) as SourceColumn
          FROM TableA a CROSS JOIN
               (VALUES (NULL)) v(SourceColumn)
         ) a
         ON TableB.AId = a.Id
    WHERE TableB.DestColumn <> TableA.SourceColumn;
END;

这是如何工作的?它使用范围规则在子查询中分配SourceColumn 的值。如果该列在TableA 中,则填充。如果不是,则使用v 中的值填充。但是,这并不重要,因为在这种情况下代码不会运行。唯一的目的是避免标识符错误。

【讨论】:

    猜你喜欢
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    相关资源
    最近更新 更多