XQuery: Finding rows which contain specified xml data

好久不见. 提交于 2019-12-07 17:53:55

问题


I have a table which contains many rows, each with a column named "RecordData" that contains XML data that I wish to search upon.

Three rows worth of example xml data from this column is given below:

1:

<Record>
  <RecordField ID="31" Name="Barcode1" DataTypeId="5" TypeName="String" Decimals="0" Format="" Mandatory="False">ABC123</RecordField>
</Record>

2:

<Record>
  <RecordField ID="15" Name="Field 1" DataTypeId="7" TypeName="Boolean" Decimals="0" Format="" Mandatory="False">true</RecordField>
  <RecordField ID="16" Name="Field 2" DataTypeId="5" TypeName="String" Decimals="0" Format="" Mandatory="False">purpke</RecordField>
</Record>

3:

<Record>
  <RecordField ID="15" Name="Field 1" DataTypeId="7" TypeName="Boolean" Decimals="0" Format="" Mandatory="False">true</RecordField>
  <RecordField ID="16" Name="Field 2" DataTypeId="5" TypeName="String" Decimals="0" Format="" Mandatory="False">12</RecordField>
</Record>

I am using the following SQL to try and find any table rows, that have XML data that contains a specific search term ('1' in this example).

DECLARE @SearchTerm varchar(max)
    SET @SearchTerm = '1'
    SELECT * 
    FROM MyTableOfData
    WHERE RecordFields.value('contains( (/Record/RecordField/text())[1],sql:variable("@SearchTerm"))','bit') = 1

As you will see, this relies on the search term appearing in the first "RecordField" element's text, rather than searching over ALL of the "RecordField" nodes. Meaning, the only result I get back would be row 1, rather than both rows 1 and 3.

I've done a bit of reading through the related MSDN articles, and am having a Google-fail day, as I'm not getting any closer to finding out how to remove the limitation and finally crack this.

Any help would be greatly appreciated :)

EDIT:

DECLARE @SearchTerm varchar(max)
SET @SearchTerm = '1'
select *
from MyTableOfData
    cross apply MyTableOfData.RecordFields.nodes('/Record/RecordField') as tx(r)
where  tx.r.value('.','varchar(10)') like '%'+@searchterm+'%'

throws:

Msg 493, Level 16, State 1, Line 3
The column 'r' that was returned from the nodes() method cannot be used directly. It can only be used with one of the four XML data type methods, exist(), nodes(), query(), and value(), or in IS NULL and IS NOT NULL checks.

EDIT 2:

And when you copy exactly what you're told, instead of missing things, this works!:

DECLARE @SearchTerm varchar(max)
SET @SearchTerm = '1'
select MyTableOfData.*
from MyTableOfData
    cross apply MyTableOfData.RecordFields.nodes('/Record/RecordField') as tx(r)
where  tx.r.value('.','varchar(10)') like '%'+@searchterm+'%'

回答1:


CROSS APPLY is what you've failed to find...

select yourtable.*
from yourtable
    cross apply yourtable.RecordFields.nodes('/Record/RecordField') as tx(r)
where  tx.r.value('.','varchar(10)') like '%'+@searchterm+'%'

or

where tx.r.value('contains((.),sql:variable("@searchterm"))','bit')=1



回答2:


You can use exist.

select *
from MyTableOfData
where RecordFields.exist('/Record/RecordField[contains(., sql:variable("@SearchTerm"))]') = 1


来源:https://stackoverflow.com/questions/11738010/xquery-finding-rows-which-contain-specified-xml-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!