具有多个XML属性的SQL WHERE子句

时间:2018-09-17 08:20:28

标签: sql xml tsql xquery

我在数据库中有XML列的表。现在,我需要通过XML的两个属性选择一些行。 到目前为止,我已经提出了以下建议:

SELECT o.Id 
FROM Objects o 
WHERE o.SerializedObject.value('(/object/param[@id="111"]/@value)[1]', 'varchar(8)') = '-1'
  AND o.SerializedObject.value('(/object/param[@id="222"]/@value)[1]', 'varchar(8)') = '8'

编辑:

XML就像:

<object>
   <param id="1" value="111"/>
   <param id="2" value="222"/>
   ...
   <param id="200" value="4545"/>
<object>

每个对象都有〜2k个参数。

我想知道使用单个XML查询是否有更好的方法。

1 个答案:

答案 0 :(得分:1)

这取决于您的XML(您没有显示示例,但是我认为这是一种EAV)。

您可以尝试使用XML的方法.exist()

DECLARE @mockup TABLE(ID INT IDENTITY,Comment VARCHAR(100),SerializedObject XML);
INSERT INTO @mockup VALUES
 ('just one of them','<object><param id="111" value="-1"/></object>')
,('both, but wrong values','<object><param id="111" value="-1"/><param id="222" value="-1"/></object>')
,('both, should fit','<object><param id="111" value="-1"/><param id="222" value="8"/></object>')

SELECT o.Id,o.Comment,o.SerializedObject
FROM @mockup o 
WHERE o.SerializedObject.exist('/object[param[@id="111" and @value="-1"] and param[@id="222" and @value="8"]]')=1;

.exist()在这里最快,因为它不返回任何值。它将仅在发现的第一个出现时返回1。当出现<param id="111" value="???">的次数很多时,这特别快。否则,您将必须切碎整个批次并将过滤器放在整个结果集上。

然后-当然! -必要的提示:正如Jeroen Mostert在评论中所说,处理更大的XML可能会成为瓶颈。如果您更经常需要此功能,则可以考虑使用关系设计而不是大型XML ...