我有一个表,具有XML字段(描述符)的实体,如下所示:
<component uid="a1">
<files>
<group name="component">
<file path="a1.bmp" md5="0315DBA4FBEEB917F41AFF1A1BFF549B" />
<file path="a2.jpg" md5="C3107D8BFA0EF0C02434FB7FC7472EAC" />
<file path="a3.bmp" md5="603B9635A4921C25D50844254A2B573D" />
<file path="a4.ini" md5="9C12CC7F5C1F1F4240DA407F7E3B145E" />
</group>
</files>
</component>我希望找到具有特定md5值的“文件”的实体:
select ... from ...
where Descriptor.value('(/component/files/group/file/@md5)[1]',
'nvarchar(100)')='C3107D8BFA0EF0C02434FB7FC7472EAC'问题是,当第一个文件具有特定的md5值时,它会找到该项。我想要的是当任何一个文件项都有特定的md5值时。
发布于 2017-01-25 08:21:45
您可以使用XML-方法exist()来检查是否存在一个元素。
我使用一个声明的表变量来模拟您的场景。插入三个不同的案例:
DECLARE @dummy TABLE(EntityID INT IDENTITY,SomeText VARCHAR(100),Descriptor XML);
INSERT INTO @dummy VALUES
('MD5 03... on first place',
N'<component uid="a1">
<files>
<group name="component">
<file path="a1.bmp" md5="0315DBA4FBEEB917F41AFF1A1BFF549B" />
<file path="a2.jpg" md5="C3107D8BFA0EF0C02434FB7FC7472EAC" />
<file path="a3.bmp" md5="603B9635A4921C25D50844254A2B573D" />
<file path="a4.ini" md5="9C12CC7F5C1F1F4240DA407F7E3B145E" />
</group>
</files>
</component>')
,('MD5 03... somewhere',
N'<component uid="a1">
<files>
<group name="component">
<file path="a2.jpg" md5="C3107D8BFA0EF0C02434FB7FC7472EAC" />
<file path="a3.bmp" md5="603B9635A4921C25D50844254A2B573D" />
<file path="a1.bmp" md5="0315DBA4FBEEB917F41AFF1A1BFF549B" />
<file path="a4.ini" md5="9C12CC7F5C1F1F4240DA407F7E3B145E" />
</group>
</files>
</component>')
,('MD5 03... not existing',
N'<component uid="a1">
<files>
<group name="component">
<file path="a2.jpg" md5="C3107D8BFA0EF0C02434FB7FC7472EAC" />
<file path="a3.bmp" md5="603B9635A4921C25D50844254A2B573D" />
<file path="a4.ini" md5="9C12CC7F5C1F1F4240DA407F7E3B145E" />
</group>
</files>
</component>');这是一个硬编码查询:
SELECT *
FROM @dummy
WHERE Descriptor.exist('/component/files/group/file[@md5="0315DBA4FBEEB917F41AFF1A1BFF549B"]')=1;但是,您可能希望将搜索值作为sql变量参数引入。
DECLARE @md5 VARCHAR(100)='0315DBA4FBEEB917F41AFF1A1BFF549B';
SELECT *
FROM @dummy
WHERE Descriptor.exist('/component/files/group/file[@md5=sql:variable("@md5")]')=1;如果这个MD5可以定位在不同的地方,您也可以检查一下深度搜索。
DECLARE @md5 VARCHAR(100)='0315DBA4FBEEB917F41AFF1A1BFF549B';
SELECT *
FROM @dummy
WHERE Descriptor.exist('//file[@md5=sql:variable("@md5")]')=1;提示
搜索XML-数据永远不会是性能.我强烈建议--如果您更经常地需要这样做,如果性能很重要,使用MD5维护一个侧表--值和行I。您可以使用类似的索引。我不会走XML索引的路.
https://stackoverflow.com/questions/41846425
复制相似问题