使用数据迁移脚本时出现“无效的列名称”错误

Den*_*nis 4 sql-server dacpac sql-server-data-tools

我的 SSDT 项目中有几个数据迁移脚本。

第一个将数据从一个表存储到另一个临时表:

IF EXISTS 
(
    SELECT * 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE table_name = N'DocumentEvent'
    AND column_name = N'Thumbprint'
)
BEGIN
    IF NOT EXISTS
    (
        SELECT * FROM INFORMATION_SCHEMA.TABLES 
        WHERE TABLE_NAME = N'tmp_DocumentEventCertificates'
    )
    BEGIN
        CREATE TABLE tmp_DocumentEventCertificates
        (
            [EventId] UNIQUEIDENTIFIER NOT NULL,
            [Thumbprint] nvarchar(100)
        )
    END

    INSERT INTO
        tmp_DocumentEventCertificates
    SELECT
        [EventId],
        [Thumbprint]
    FROM
        [DocumentEvent]
    WHERE
        [Thumbprint] IS NOT NULL
END
Run Code Online (Sandbox Code Playgroud)

第二个将数据从临时表传输到另一个表:

IF EXISTS
(
    SELECT * FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_NAME = N'tmp_DocumentEventCertificates'
)
BEGIN
    UPDATE
        [DocumentAttachment]
    SET
        [DocumentAttachment].[Certificate_Thumbprint] = tmp.[Thumbprint]
    FROM
        tmp_DocumentEventCertificates AS tmp
    WHERE
        ([DocumentAttachment].[EventId] = tmp.[EventId]) AND
        ([DocumentAttachment].[ParentDocumentAttachmentId] IS NOT NULL)

    DROP TABLE tmp_DocumentEventCertificates
END
Run Code Online (Sandbox Code Playgroud)

[Thumbprint]正在从表中删除列[DocumentEvent]
[Certificate_Thumbprint]正在添加到[DocumentAttachment]表中。

数据必须从 传输[DocumentEvent].[Thumbprint][DocumentAttachment].[Certificate_Thumbprint]

当数据库处于需要从上面迁移的状态(即[DocumentEvent].[Thumbprint] 存在[DocumentAttachment].[Certificate_Thumbprint] 不存在)时,这些脚本按预期工作。

但是,当数据库迁移时,所有部署 dacpac 的尝试都会因“无效的列名‘Thumbprint’”错误而失败。

我几乎可以肯定,发生这种情况是因为 SQLCMD 尝试编译整个部署脚本,并且只有在[DocumentEvent].[Thumbprint]存在时才能成功完成。

但解决方法是什么?

看起来IF EXISTS第一个脚本没有帮助。

sep*_*pic 6

是的,你没看错,是编译错误。如果该列不存在,则无法编译您的脚本。IF Exists 和其他数据流结构不进行分析。

您应该将产生编译错误的代码包装在 EXEC 中:

exec(
'INSERT INTO
        tmp_DocumentEventCertificates
    SELECT
        [EventId],
        [Thumbprint]
    FROM
        [DocumentEvent]
    WHERE
        [Thumbprint] IS NOT NULL')
Run Code Online (Sandbox Code Playgroud)