最初我有一个partner_email
类型为 () 的列varchar
。现在最近发生了一个变化,需要将其更改为XML
数据类型,但需要将现有行转换为新列。
需要帮助
最初我有一个partner_email
类型为 () 的列varchar
。现在最近发生了一个变化,需要将其更改为XML
数据类型,但需要将现有行转换为新列。
需要帮助
单步执行脚本将有助于理解问题:
脚本 1
partner_email_temp
Partner 表中不存在该列,则添加partner_email_temp
为 XML 列partner_email_temp
XML 友好的字符串版本partner_email
。然后将其转换为 XML。使用 REPLACE 将所有 & 转换为编码的 &partner_email
从合作伙伴中删除列partner_email_temp
为partner_email
所有这些都是第一次工作。当您第二次运行该脚本时,SQL Server 会进入第 2 步并再次执行 ALTER TABLE 语句。这是因为该列partner_email_temp
不存在(它在第一次运行时被重命名为 partner_email)。
现在在第 3 步中,您正在尝试partner_email
再次更新该列。问题是这个列现在是一个 XML 数据类型并且你的使用REPLACE
是非法的。所以 SQL Server 会抛出一个错误。
脚本 2
partner_email
捕获Partner 中列的列数据类型。partner_email_temp
不存在,则将该
partner_email_temp
列添加为 XMLpartner_email_temp
XML 友好的字符串版本来更新合作伙伴表partner_email
,然后将其转换为 XML。用于REPLACE
将所有 & 转换为编码的 &partner_email
从合作伙伴中删除列partner_email_temp
为partner_email
第二个脚本中的问题是您不能GO
在 BEGIN 和 END 语句中使用该语句。
根据BOL:
SQL Server 实用程序将 GO 解释为它们应该将当前批次的 Transact-SQL 语句发送到 SQL Server 实例的信号。
因此,在脚本 2 中,当 SQL Server 尝试编译时,它会注意到该列partner_email_temp
不存在。它适用于脚本 1,因为这些部分是单独执行的。并且当执行引用的部分时partner_email_temp
,该列确实存在。
那么如何解决呢?
如果您只需将partner_email
列中的数据更新为正确的格式,然后将该列转换为 XML 数据类型,您实际上可以绕过所有列的删除和重命名。这可以在一个 SQL 批处理语句中实现,但您需要将其作为动态 SQL 执行,以便 SQL Server 仅在 varchar 数据类型REPLACE
时尝试执行该语句:partner_email column
IF NOT EXISTS
(
SELECT *
FROM INFORMATION_SCHEMA.columns
WHERE table_name = 'Partner'
AND column_name = 'partner_email'
AND data_type = 'xml'
)
BEGIN
DECLARE @sqlCmd NVARCHAR(4000)
SET @sqlCmd = N'
UPDATE [dbo].[Partner]
SET partner_email = ''<PartnerEmails><Email>''
+ REPLACE(partner_email, ''&'', ''&'')
+ ''</Email><Email></Email><Email></Email></PartnerEmails>'';
ALTER TABLE Partner ALTER Column partner_email XML
'
EXEC (@sqlCmd)
END