Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有多个XML属性的SQL WHERE子句_Sql_Xml_Tsql_Xquery - Fatal编程技术网

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

具有多个XML属性的SQL WHERE子句,sql,xml,tsql,xquery,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]', '

我在数据库中有一个包含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查询来实现这一点。

这取决于您的XML(您没有给出示例,但我假设这是一种EAV)

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

DECLARE@mockup表(ID INT-IDENTITY,Comment-VARCHAR(100),SerializedObject-XML);
插入到@mockup值中
(“只是其中之一,”)
,(“两者都有,但值错误”,“”)
,(“两者都应该适合”,“”)
选择o.Id、o.Comment、o.SerializedObject
来自@mockup o
其中o.SerializedObject.exist('/object[param[@id=“111”和@value=“-1”]和param[@id=“222”和@value=“8”]])=1;
.exist()
在这里是最快的,因为它不返回任何值。它只会在第一次发现时返回
1
。这是特别快的,当一个
发生了很多次时,否则你必须将整个批次切碎,并将过滤器放在整个结果集上


当然啦必要的提示:正如Jeroen Mostert在一篇评论中所说,处理更大的XML可能会成为一个瓶颈。如果您更经常需要它,您可以考虑使用关系设计而不是大型XML…

为什么不先将XML解析到临时表中呢。应用where或其他操作将更容易每个XML中都有~2k个节点,因此我认为选择临时表的值是不有效的。在一个XML中可能会有重复的
@id=“111”
?如果我理解正确,你是在检查某些组合的存在性。。。我想临时表会产生相当大的开销……对于2K个节点,无论是否使用临时表,您都会从这些查询中看到相当差的性能。如果这不是一次性查询,您可以考虑查看XML索引,或者预先分割专用列中的一些节点。不用说,完全关系结构(通过将整个内容扩展到一个表中)的性能总是会更好。
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;