3

我有一个包含许多行的表,每行都有一个名为“RecordData”的列,其中包含我希望搜索的 XML 数据。

下面给出了来自该列的三行示例 xml 数据:

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>

我正在使用以下 SQL 来尝试查找任何具有包含特定搜索词(本示例中为“1”)的 XML 数据的表行。

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

正如您将看到的,这依赖于出现在第一个“RecordField”元素文本中的搜索词,而不是搜索所有“RecordField”节点。意思是,我得到的唯一结果是第 1 行,而不是第 1 行和第 3 行。

我已经阅读了一些相关的 MSDN 文章,并且正在经历谷歌失败的一天,因为我没有更接近于找出如何消除限制并最终破解它。

任何帮助将不胜感激 :)

编辑:

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+'%'

抛出:

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.

编辑2:

当你准确地复制你被告知的内容时,而不是丢失东西,这有效!:

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+'%'
4

2 回答 2

3

CROSS APPLY是你没找到的...

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

或者

where tx.r.value('contains((.),sql:variable("@searchterm"))','bit')=1
于 2012-07-31T10:34:02.410 回答
3

您可以使用存在

select *
from MyTableOfData
where RecordFields.exist('/Record/RecordField[contains(., sql:variable("@SearchTerm"))]') = 1
于 2012-07-31T19:18:41.517 回答