2011-10-10 20 views
5

tienen un problema con signo (&)texto de SQL Server Buscar comercial (&)

Cómo buscar las palabras (o frases) que contienen un signo (&).

Por ejemplo, en la base de datos son:

1: "Johnson & Johnson" 
2: "AT&T" 
3: "Sample & Sample" 

¿Cómo debo escribir una búsqueda de texto completo de consulta para buscar registros individuales?

SELECT * from Companies c WHERE CONTAINS(c.CompanyName, '"AT&T"') 

sé que carácter (&) es responsable de la operación lógica AND. Pero no sé cómo codificarlo para buscar texto con el uso de búsqueda de texto completo.

¿Alguna idea?

Respuesta

5

versión corta: Usted no puede (o al menos se puede, pero usted puede obtener más resultados de los esperados)

Versión larga:'&' El carácter es tratado como un "separador de palabras" , es decir, cuando SQL Server encuentra un '&', lo trata como el inicio de una nueva "palabra" (es decir, token). Lo que SQL Server ve al analizar "AT&T" son dos tokens, "AT" y "T".

Esto se puede comprobar por sí mismo utilizando sys.dm_fts_parser:

SELECT * FROM sys.dm_fts_parser('AT&T', 1033, 0, 0) 

keyword  group_id phrase_id occurrence special_term display_term expansion_type source_term 
----------- ----------- ----------- ----------- ------------- ------------- -------------- ----------- 
0x00610074 1   0   1   Noise Word at   0    AT 
0x0074  2   0   1   Noise Word t    0    T 

Esto significa que la búsqueda de "AT&T" es casi exactamente el mismo que acaba de búsqueda de "AT T".

Esto es por diseño, por lo que puedo ver, la única forma de modificar este comportamiento sería instalar su propio word breaker, sin embargo, esto no es algo que recomendaría hacer.

2

La respuesta aceptada no es completamente correcta. Encerrar el término de búsqueda entre comillas dobles hace que la agrupación de palabras sea una coincidencia de "frase". En este caso, los amplificadores y (&) pueden ser tratados como un carácter literal, como cuando están rodeados por una o más letras que no forman una palabra conocida. Con sólo mirar su ejemplo "AT&T", vemos:

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"AT&T"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

Devuelve:

keyword    group phrase occurrence special  display expansion source 
        id  id     term   term  type  term 
0x0061007400260074 1  0  1   Exact Match at&t  0   AT&T 

Como se puede ver, el símbolo de unión no presenta ningún problema en absoluto, con tal de que se encierra entre comillas dobles (") que ya estás haciendo, woo hoo!

Sin embargo, que no funciona tan limpiamente para el "Johnson & Johnson" ejemplo:

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"Johnson & Johnson"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

Devuelve:

keyword       group phrase occurrence special  display expansion source 
           id  id     term   term  type  term 
0x006A006F0068006E0073006F006E 1  0  1   Exact Match johnson 0   Johnson & Johnson 
0x006A006F0068006E0073006F006E 1  0  2   Exact Match johnson 0   Johnson & Johnson 

que parecería coincidir también un término de búsqueda de Johnson Johnson, que no es técnicamente correcto.

Así, además de encerrar entre comillas dobles, también puede convertir el signo de ser un guión bajo (_) que se maneja de manera diferente:

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"Johnson _ Johnson"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 
GO 

devoluciones:

keyword       group phrase occurrence special  display expansion source 
           id  id     term   term  type  term 
0x006A006F0068006E0073006F006E 1  0  1   Exact Match johnson 0   Johnson _ Johnson 
0x005F       1  0  2   Exact Match _  0   Johnson _ Johnson 
0x006A006F0068006E0073006F006E 1  0  3   Exact Match johnson 0   Johnson _ Johnson 

Y , al hacer eso, la traducción de un carácter no parece afectar negativamente a la búsqueda original "AT&T":

DECLARE @Term NVARCHAR(100); 
SET @Term = N'"AT_T"'; 

SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, 0, 1); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 0); 
SELECT * FROM sys.dm_fts_parser(@Term, 1033, NULL, 1); 

Devoluciones:

keyword    group phrase occurrence special  display expansion source 
        id  id     term   term  type  term 
0x00610074005F0074 1  0  1   Exact Match at_t  0   AT_T