更新 XML 数据类型而不创建重复节点
Update XML data type without creating duplicate nodes
在我的应用程序中,用户可以select 组技能进行搜索,这些技能存储为XML。在这个简单的例子中,我在 table 中有以下结构,其中包含一个 XML 主索引。
CREATE TABLE #myTable (ID int IDENTITY(1,1) PRIMARY KEY, userId int NOT NULL, searchXml xml not null);
GO
CREATE PRIMARY XML INDEX [Ix1] ON #myTable (searchXml) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
INSERT INTO #myTable (userId, searchXml) VALUES
(1, '<search><skills><s id="4" /><s id="10" /></skills></search>'),
(1, '<search><skills><s id="4" /><s id="8" /><s id="10" /></skills></search>'),
(2, '<search><skills><s id="7" /><s id="8" /><s id="10" /></skills></search>'),
(3, '<search><skills><s id="4" /><s id="10" /><s id="11" /></skills></search>');
SELECT * FROM #myTable;
DROP TABLE #myTable;
GO
我需要执行以下更新,但经过长时间的阅读后,甚至无法接近:
技能ID 4要和技能ID 8合并,只剩下技能ID 8。
因此,每条XML条数据需要按如下方式更新:
- 如果4&8存在于同一个XML,去掉4,只留下8
- 如果4是孤立存在的,那么把4改成8
- 如果8孤立存在,不采取任何行动
任何人都可以通过分享解决方案来帮助我提高 XML 技能吗?
我可以通过两次更新来完成:
- If 4 & 8 exist in the same XML, remove 4, leaving only 8
UPDATE #myTable
SET searchXml.modify('
delete (/search/skills[data(s/@id)=4 and data(s/@id)=8]/s[@id=4])')
并且如果每个技能元素只允许出现一次 <s id="4"/>
,并且每次搜索只允许出现一个技能元素,并且只允许出现一个搜索元素:
- If 4 exists in isolation, then change 4 to 8
UPDATE #myTable
SET searchXml.modify('
replace value of
(/search/skills[data(s/@id)=4 and not(data(s/@id)=8)]/s[@id=4]/@id)[1]
with 8 ')
在我的应用程序中,用户可以select 组技能进行搜索,这些技能存储为XML。在这个简单的例子中,我在 table 中有以下结构,其中包含一个 XML 主索引。
CREATE TABLE #myTable (ID int IDENTITY(1,1) PRIMARY KEY, userId int NOT NULL, searchXml xml not null);
GO
CREATE PRIMARY XML INDEX [Ix1] ON #myTable (searchXml) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
INSERT INTO #myTable (userId, searchXml) VALUES
(1, '<search><skills><s id="4" /><s id="10" /></skills></search>'),
(1, '<search><skills><s id="4" /><s id="8" /><s id="10" /></skills></search>'),
(2, '<search><skills><s id="7" /><s id="8" /><s id="10" /></skills></search>'),
(3, '<search><skills><s id="4" /><s id="10" /><s id="11" /></skills></search>');
SELECT * FROM #myTable;
DROP TABLE #myTable;
GO
我需要执行以下更新,但经过长时间的阅读后,甚至无法接近:
技能ID 4要和技能ID 8合并,只剩下技能ID 8。 因此,每条XML条数据需要按如下方式更新:
- 如果4&8存在于同一个XML,去掉4,只留下8
- 如果4是孤立存在的,那么把4改成8
- 如果8孤立存在,不采取任何行动
任何人都可以通过分享解决方案来帮助我提高 XML 技能吗?
我可以通过两次更新来完成:
- If 4 & 8 exist in the same XML, remove 4, leaving only 8
UPDATE #myTable
SET searchXml.modify('
delete (/search/skills[data(s/@id)=4 and data(s/@id)=8]/s[@id=4])')
并且如果每个技能元素只允许出现一次 <s id="4"/>
,并且每次搜索只允许出现一个技能元素,并且只允许出现一个搜索元素:
- If 4 exists in isolation, then change 4 to 8
UPDATE #myTable
SET searchXml.modify('
replace value of
(/search/skills[data(s/@id)=4 and not(data(s/@id)=8)]/s[@id=4]/@id)[1]
with 8 ')