SQL Server XML 데이터 형식에서 LIKE 문 사용


87

varchar 필드가 SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%'있으면 해당 열에 특정 문자열이 포함되어 있는지 쉽게 확인할 수 있습니다 .

XML 유형에 대해 어떻게 수행합니까?

'텍스트'노드가있는 행만 반환하는 다음이 있지만 해당 노드 내에서 검색해야합니다.

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

답변:


70

이 작업을 아주 쉽게 할 수 있어야합니다.

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

.value메서드는 실제 값을 제공하고이를 VARCHAR ()로 반환되도록 정의 할 수 있으며, 그런 다음 LIKE 문으로 확인할 수 있습니다.

이건 엄청 빠르지는 않을 거라는 걸 명심하세요. 따라서 XML에 많은 검사가 필요한 특정 필드가있는 경우 다음을 수행 할 수 있습니다.

  • XML을 가져오고 찾고있는 값을 VARCHAR ()로 반환하는 저장 함수를 만듭니다.
  • 이 함수를 호출하는 테이블에 새 계산 필드를 정의하고 PERSISTED 열로 만듭니다.

이를 통해 기본적으로 XML의 특정 부분을 계산 된 필드로 "추출"하고 지속되도록 만든 다음이를 매우 효율적으로 검색 할 수 있습니다 (해당 필드를 INDEX 할 수도 있습니다!).

마크


1
기본적으로 검색 기능을 구현하고 있으므로 '텍스트'노드에서만 XML 열을 검색 한 다음 검색에서 일치하는 항목을 찾았 음을 나타내는 하위 문자열을 반환하고 싶습니다. 예를 들어 전체 xml 열을 반환하는 대신 'hi there'를 검색하면 'the chap said hi there and carry ...'와 같은 하위 문자열 만 반환됩니다.
Jon

1
저를 5 초로 이겼습니다. 또 다른 가능성은 데이터가
적절

10
전체 파일 검색 : WHERE xmlField.value ( '.', 'varchar (max)') LIKE '% FOO %'
jhilden

당신은 NULL을 다시 얻는 경우에 성가신 XML 네임 스페이스에 대한 조심
Simon_Weaver

87

또 다른 옵션은 XML을 nvarchar로 캐스팅 한 다음 XML vas가 nvarchar 필드 인 것처럼 주어진 문자열을 검색하는 것입니다.

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

이 솔루션은 깨끗하고 기억하기 쉽고 엉망이되기 어렵고 where 절의 일부로 사용할 수 있으므로이 솔루션을 좋아합니다.

편집 : Cliff가 언급했듯이 다음을 사용할 수 있습니다.

... varchar로 변환되지 않는 문자가있는 경우 nvarchar


3
그에 동감, 또는 NVARCHAR WHERE CAST 표 * FROM VARCHAR SELECT로 변환하지 않는 문자가 있다면 (열 등 NVARCHAR (최대)) LIKE '% 테스트 %'
클리프 풀 베는

[Err] 42000-[SQL Server] 하나 이상의 문자를 XML에서 대상 데이터 정렬로 변환 할 수 없음
digz6666

[Err] 22018-[SQL Server] 데이터 유형 xml에서 텍스트로의 명시 적 변환이 허용되지 않습니다.
digz6666

@ digz6666
Squazz

1
@Squazz 어제이 답변에 마지막으로 투표하셨습니다. 이 답변을 편집하지 않는 한 귀하의 투표는 이제 잠겨 있습니다. :)
digz6666

10

또 다른 옵션은 XML을 문자열로 변환 한 다음 LIKE를 사용하여 문자열로 검색하는 것입니다. 그러나 계산 열은 WHERE 절의 일부가 될 수 없으므로 다음과 같이 다른 SELECT로 래핑해야합니다.

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

이것은 당신이 가지고있을 수있는 선택적인 xml 색인을 우회하고 성능에 영향을 미칠 수 있음을 알려드립니다.
Rudy Hinojosa

0

이것은 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

검색 기준이있는 검색에서 하위 문자열을 반환합니다.


어떻게 든 주입을 방지하기 위해 매개 변수가 필요합니까?
Jon

2
주의하십시오 : 이러한 XML 함수는 대소 문자를 구분합니다. DATA.VALUE 작동 하지 않습니다 ! 그것은하는 필요가있다 (...) .value
marc_s
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.