有人知道如何批量更新 SQL Server 数据库中的列吗?
情况如下:我有一个列
Config
定义为 nvarchar(max)
,但它包含格式化的 XML。
这是一个例子:
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfLearningPathItem xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LearningPathItem xsi:type="type">
<Id>id</Id>
<Title>title</Title>
<Content><iframe allowfullscreen src="https://site.sharepoint.com/sites/site/SitePages/page.aspx" width="100%" height="100%" data-embedSize="3"></iframe></Content>
<EmbedType>typeType</EmbedType>
</LearningPathItem>
</ArrayOfLearningPathItem>
我需要批量更新那里的内容元素,因此代码将被删除,只保留网址。
因此从这个示例来看,结果应该是 https://site.sharepoint.com/sites/site/SitePages/page.aspx
我尝试将列转换为xml,将其放入临时表,搜索带有sharepoint链接的所有元素并使用新内容更新它们,然后将临时表与旧表连接起来。
但是,我仍然找不到从代码中剪切 url 的方法。对于其他元素来说更容易,如果我只更改 EmbedType 参数,效果会很好:
UPDATE @TempTable
SET ConfigXML.modify('
replace value of (/ArrayOfLearningPathItem/LearningPathItem[EmbedType="type1" and Content[contains(text()[1], "sharepoint.com")]]/EmbedType/text())[1]
with
"type2"
');
对于url我猜想这样的东西可以工作,如果substring-before和substring-after可以在xml修改方法中使用,但只能使用substring
UPDATE @TempTable
SET ConfigXML.modify('
replace value of (/ArrayOfLearningPathItem/LearningPathItem[EmbedType="type1" and Content[contains(text()[1], "sharepoint.com")]]/Content/text())[1]
with
substring-before(substring-after(/ArrayOfLearningPathItem/LearningPathItem[EmbedType="type1" and Content[contains(text()[1], "sharepoint.com")]]/Content/text(), "src=""), """)
');
不幸的是,SQL Server 不支持大多数新的 XQuery 函数。您需要将数据提取到 SQL 中,使用
CHARINDEX
和 SUBSTRING
获取正确的数据,然后使用 sql:column
将其推回 XQuery
UPDATE t
SET ConfigXML.modify('
replace value of (
/ArrayOfLearningPathItem/LearningPathItem
[EmbedType="type1" and Content[contains(text()[1], "sharepoint.com")]]
/Content/text()
)[1]
with sql:column("v3.url")
')
FROM @TempTable t
CROSS APPLY (
SELECT ContentValue =
T.ConfigXML.value('
(/ArrayOfLearningPathItem/LearningPathItem
[EmbedType="type1" and Content[contains(text()[1], "sharepoint.com")]]
/Content/text())[1]', 'nvarchar(max)')
) x1
CROSS APPLY (
SELECT src = NULLIF(CHARINDEX('src="', x1.ContentValue), 0) + 5
) v1
CROSS APPLY (
SELECT quote = NULLIF(CHARINDEX('"', x1.ContentValue, v1.src), 0)
) v2
CROSS APPLY (
SELECT url = SUBSTRING(x1.ContentValue, v1.src, v2.quote - v1.src)
) v3;