"Invalid column name" 使用数据迁移脚本时出错
"Invalid column name" error when using data migration scripts
我的 SSDT 项目中有几个数据迁移脚本。
第一个将数据从一个 table 存储到另一个临时 table:
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
第二个将数据从临时 table 传输到另一个 table:
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
正在从 [DocumentEvent]
table 中删除列 [Thumbprint]
。
正在将列 [Certificate_Thumbprint]
添加到 [DocumentAttachment]
table.
数据必须从 [DocumentEvent].[Thumbprint]
传输到 [DocumentAttachment].[Certificate_Thumbprint]
。
这些脚本按预期工作,当数据库处于需要从上面迁移的状态时,即 [DocumentEvent].[Thumbprint]
存在 和 [DocumentAttachment].[Certificate_Thumbprint]
不存在.
但是当迁移数据库时,所有部署 dacpac 的尝试都失败了,因为
"Invalid column name 'Thumbprint'" 错误。
我几乎可以肯定,发生这种情况是因为 SQLCMD 试图编译整个部署脚本,并且只有在 [DocumentEvent].[Thumbprint]
存在时才能成功完成。
但是解决方法是什么?
第一个脚本中的 IF EXISTS
似乎无济于事。
是的,你没看错,是编译错误。
如果该列不存在,则无法编译您的脚本。
IF Exists等数据流构造不分析
您应该将产生编译错误的代码包装在 EXEC 中:
exec(
'INSERT INTO
tmp_DocumentEventCertificates
SELECT
[EventId],
[Thumbprint]
FROM
[DocumentEvent]
WHERE
[Thumbprint] IS NOT NULL')
我的 SSDT 项目中有几个数据迁移脚本。
第一个将数据从一个 table 存储到另一个临时 table:
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
第二个将数据从临时 table 传输到另一个 table:
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
正在从 [DocumentEvent]
table 中删除列 [Thumbprint]
。
正在将列 [Certificate_Thumbprint]
添加到 [DocumentAttachment]
table.
数据必须从 [DocumentEvent].[Thumbprint]
传输到 [DocumentAttachment].[Certificate_Thumbprint]
。
这些脚本按预期工作,当数据库处于需要从上面迁移的状态时,即 [DocumentEvent].[Thumbprint]
存在 和 [DocumentAttachment].[Certificate_Thumbprint]
不存在.
但是当迁移数据库时,所有部署 dacpac 的尝试都失败了,因为 "Invalid column name 'Thumbprint'" 错误。
我几乎可以肯定,发生这种情况是因为 SQLCMD 试图编译整个部署脚本,并且只有在 [DocumentEvent].[Thumbprint]
存在时才能成功完成。
但是解决方法是什么?
第一个脚本中的 IF EXISTS
似乎无济于事。
是的,你没看错,是编译错误。 如果该列不存在,则无法编译您的脚本。 IF Exists等数据流构造不分析
您应该将产生编译错误的代码包装在 EXEC 中:
exec(
'INSERT INTO
tmp_DocumentEventCertificates
SELECT
[EventId],
[Thumbprint]
FROM
[DocumentEvent]
WHERE
[Thumbprint] IS NOT NULL')