2009-12-02 3 views
55

Если у вас есть поле varchar, вы можете легко сделать SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%', чтобы увидеть, содержит ли этот столбец определенную строку.Используйте инструкцию LIKE для SQL Server XML Тип данных

Как вы это делаете для типа XML?

У меня есть следующее, который возвращает только те строки, которые имеют узел «Текст», но мне нужно искать в этом узле

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

возможный дубликат [Лучший способ поиска данных, хранящихся как XML в Sql Server?] (http://stackoverflow.com/questions/52945/best-way-to-search-data-stored-as-xml-in-sql-server) –

ответ

53

Вы должны быть в состоянии сделать это довольно легко:

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

Метод .value дает вам фактическое значение, и вы можете определить, что будет возвращено как VARCHAR(), которое вы можете проверить с помощью инструкции LIKE.

Помните, что это не будет ужасно быстро. Так что если у вас есть определенные поля в вашем XML, что вам нужно, чтобы проверить много, вы можете:

  • создать хранимую функцию, которая получает в XML и возвращает значение, которое вы ищете, как VARCHAR()
  • определить новое вычисляемое поле на вашем столе, который вызывает эту функцию, и сделать его PERSISTED колонку

с этим, вы в основном «извлечь» определенную часть XML в вычисляемое поле, сделать это сохранялось , а затем вы можете очень эффективно искать на нем (черт: вы можете даже индексировать это поле!).

Марк

+1

Я в основном реализую поиск , поэтому я хочу искать столбец XML только на узлах «Текст», а затем возвращать подстроку, чтобы указать, что поиск нашел совпадение.Например, поиск по 'hi there' вместо того, чтобы возвращать весь столбец xml, я бы просто вернул подстроку, такую ​​как «chap сказал hi there and carry ...» – Jon

+1

Ударьте меня на 5 секунд. Другая возможность - рассмотреть возможность использования бесплатного текстового поиска, если ваши данные поддаются ... – RickNZ

+6

для поиска по всей поданной: WHERE xmlField.value ('.', 'Varchar (max)') LIKE '% FOO%' – jhilden

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 

Возвращение подстроки на поиске, где критерии поиска существует

+0

Do I нужны параметры для предотвращения инъекций? – Jon

+2

БУДЬТЕ ЗНАЧИТ: эти функции XML имеют чувствительность к регистру - DATA.VALUE ** не будут работать **! Это необходимо для **. Value (...) ** –

+1

Просто заметили, что – Jon

10

Другим вариантом является поиск в XML как строку, преобразовывая его в строку, а затем используя LIKE. Однако, как вычисляемый столбец не может быть частью ИНЕКЯ вам нужно обернуть его в другом ВЫБРАТЬ так:

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

Еще один вариант бросить XML как NVARCHAR, а затем поиск заданной строки как будто XML представляет собой поле nvarchar.

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

Я люблю это решение, как это чистый, легко запомнить, трудно испортить, и может быть использован в качестве части, где положение.

EDIT: Как Клифф упоминает о нем, вы можете использовать:

... NVARCHAR, если есть символы, которые не преобразовывают в VARCHAR

+2

То же самое на nvarchar, если есть символы, которые не конвертировать в varchar SELECT * FROM Таблица WHERE CAST (Столбец как nvarchar (max)) LIKE '% TEST%' –

+0

[Err] 42000 - [SQL Server] Преобразование одного или нескольких символов из XML в целевое сопоставление невозможно – digz6666

+0

[Err ] 22018 - [SQL Server] Явное преобразование из типа данных xml в текст не допускается. – digz6666

Смежные вопросы