web-dev-qa-db-ja.com

SQL Server XMLデータ型でLIKEステートメントを使用する

Varcharフィールドがある場合は、SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%'は、その列に特定の文字列が含まれているかどうかを確認します。

XML Typeについてはどうしますか?

「テキスト」ノードを持つ行のみを返す次のものがありますが、そのノード内で検索する必要があります

select * from WebPageContent where data.exist('/PageContent/Text') = 1
72
Jon

これは非常に簡単にできるはずです。

SELECT * 
FROM WebPageContent 
WHERE data.value('(/PageContent/Text)[1]', 'varchar(100)') LIKE 'XYZ%'

.valueメソッドは実際の値を提供し、それをVARCHAR()として返すように定義できます。これをLIKEステートメントで確認できます。

気を付けてください、これは非常に高速になることはありません。したがって、XMLに特定のフィールドがあり、多くの検査が必要な場合は、次のことができます。

  • xMLを取得し、探している値をVARCHAR()として返すストアド関数を作成します
  • この関数を呼び出す新しい計算フィールドをテーブルに定義し、PERSISTED列にします

これにより、基本的にXMLの特定の部分を計算フィールドに「抽出」し、それを永続化して、非常に効率的に検索できます(そのフィールドにINDEXを付けることさえできます!)。

マーク

67
marc_s

さらに別のオプションは、XMLをnvarcharとしてキャストし、XMLがnvarcharフィールドにあるかのように指定された文字列を検索することです。

SELECT * 
FROM Table
WHERE CAST(Column as nvarchar(max)) LIKE '%TEST%'

このソリューションは、クリーンで、覚えやすく、混乱しにくく、where句の一部として使用できるため、気に入っています。

編集:クリフが言及しているように、あなたは使用することができます:

...nvarchar。varcharに変換されない文字がある場合

63
Squazz

もう1つのオプションは、XMLを文字列に変換してからLIKEを使用して、XMLを文字列として検索することです。ただし、計算列をWHERE句の一部にすることはできないため、次のように別のSELECTでラップする必要があります。

SELECT * FROM
    (SELECT *, CONVERT(varchar(MAX), [COLUMNA]) as [XMLDataString] FROM TABLE) x
WHERE [XMLDataString] like '%Test%'
10
Carl Onager

これは、marc_sの回答に基づいて使用するものです。

SELECT 
SUBSTRING(DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)'),PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')) - 20,999)

FROM WEBPAGECONTENT 
WHERE COALESCE(PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')),0) > 0

検索条件が存在する検索の部分文字列を返します

0
Jon