2009-12-02 23 views
55

Si tiene un campo varchar puede hacer fácilmente SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%' para ver si esa columna contiene una determinada cadena.Utilice una instrucción LIKE en SQL Server XML Datatype

¿Cómo se hace eso para XML Type?

tengo los siguientes, que sólo devuelve las filas que tienen un nodo 'Texto', pero tengo que buscar dentro de ese nodo

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

posible duplicado de [La mejor manera de buscar los datos almacenados como XML en Sql Server?] (http://stackoverflow.com/questions/52945/best-way-to-search-data-stored-as-xml-in-sql-server) –

Respuesta

53

Usted debe ser capaz de hacer esto con bastante facilidad:

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

El método .value le proporciona el valor real y puede definirlo para que se devuelva como VARCHAR(), que luego puede verificar con una instrucción LIKE.

Eso sí, esto no va a ser muy rápido. Así que si usted tiene ciertos campos en el código XML que usted necesita para inspeccionar una gran cantidad, usted podría:

  • crear una función almacenada que recibe el XML y devuelve el valor que está buscando como VARCHAR()
  • definir un nuevo campo calculado en su mesa, que llama a esta función, y que sea una columna PERSISTED

Con esto, usted básicamente "extraer" una cierta porción del XML en un campo calculado, que persistió , y luego puedes buscar muy eficientemente en él (diablos: ¡puedes incluso INDICAR ese campo!).

Marc

+1

Básicamente estoy implementando una búsqueda función, por lo que quiero buscar en la columna XML solo en los nodos 'Texto' y luego devolver una subcadena para indicar que la búsqueda ha encontrado una coincidencia.Por ejemplo, busque 'hola allí' en lugar de devolver toda la columna xml. Simplemente devolvería una subcadena como 'el tipo dijo hola y se llevó ...' – Jon

+1

Me adelantó 5 segundos. Otra posibilidad es considerar el uso de búsqueda de texto libre, si sus datos son susceptibles ... – RickNZ

+6

para buscar en el archivo completo: WHERE xmlField.value ('.', 'Varchar (max)') LIKE '% FOO%' – jhilden

0

Esto es lo que voy a utilizar en función de marc_s respuesta:

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 

devolver una subcadena en la búsqueda donde los criterios de búsqueda existe

+0

Do I ¿Necesita parámetros para prevenir la inyección de alguna manera? – Jon

+2

TENER EN CUENTA: las funciones XML SON sensibles a las mayúsculas y minúsculas - ¡DATA.VALUE ** no funcionará! Necesita ser **. Value (...) ** –

+1

Acabo de detectar que – Jon

10

Otra opción es buscar en el XML como una cadena convirtiéndola en una cadena y luego usando LIKE. Sin embargo, como una columna calculada no puede ser parte de una cláusula donde tiene que envolverlo en otra SELECCIONAR así:

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

Sin embargo, otra opción es convertir el XML como nvarchar y, a continuación, busque la cadena dada como si el XML fuera un campo nvarchar.

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

Me encanta esta solución, ya que es limpio, fácil de recordar, difícil de desastre, y se puede utilizar como parte de una cláusula where.

EDIT: Como lo menciona acantilado, se puede utilizar:

... nvarchar si hay caracteres que no se convierten a varchar

+2

Lo mismo ocurre con eso, o nvarchar si hay caracteres que no lo hacen convert to varchar SELECT * FROM Table WHERE CAST (Columna como nvarchar (max)) LIKE '% TEST%' –

+0

[Err] 42000 - [SQL Server] Conversión de uno o más caracteres de XML a colación de destino imposible – digz6666

+0

[Err ] 22018 - [SQL Server] La conversión explícita del tipo de datos xml al texto no está permitida. – digz6666

Cuestiones relacionadas