sql - T-SQL 中的 XPath 选择实体

标签 sql xml tsql xpath

我有一个表,带有 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 值的"file"的实体:
select ... from ...
where Descriptor.value('(/component/files/group/file/@md5)[1]',
         'nvarchar(100)')='C3107D8BFA0EF0C02434FB7FC7472EAC'

问题是当第一个文件具有特定的 md5 值时它会找到该项目。我想要的是什么时候找到任何文件项具有特定的 md5 值。

最佳答案

您可以使用 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 值和 rowID 的边表。您可以使用类似于索引。我不会走 XML 索引之路……

关于sql - T-SQL 中的 XPath 选择实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41846425/

相关文章:

sql - 有什么方法可以安全地运行 SELECT INTO 吗?

mysql - 将整数数组传递给 mysql 过程

同一属性的 SQL 数据库多个值 - 最佳实践?

java - 有没有办法在 Android Studio 中使用像 colorPrimary 这样的样式主题颜色作为我的项目背景 intsted of @color/"whateverColorYouWant"

sql - 如果前面没有相同字符,则替换字符

Python MySQL 参数化日期查询

xml - XML编辑-值为null

java - JDom 是否有任何 org.w3c.dom 包装器?

sql-server - SQL服务器2008 : Copy a file and rename it

sql - SQL Server 中的反转字符串