SQL-SERVER
Introducción
Consultas e índices de texto
El principal requisito de diseño de los índices,
consultas y sincronización de texto es la presencia de una columna
de clave exclusiva de texto (o clave principal de columna única)
en todas las tablas que se registren para realizar búsquedas de
texto. Un índice de texto realiza el seguimiento de las palabras
significativas que más se usan y dónde se encuentran.
Por ejemplo, imagine un índice de texto para la tabla DevTools.
Un índice de texto puede indicar que la palabra "Microsoft" se encuentra
en la palabra número 423 y en la palabra 982 de la columna Abstract
para la fila asociada con el ProductID igual a 6. Esta estructura
de índices admite una búsqueda eficiente de todos los elementos
que contengan palabras indizadas y operaciones de búsqueda avanzadas,
como búsquedas de frases y búsquedas de proximidad.
Para impedir que los índices de texto se inunden con palabras que
no ayudan en la búsqueda, las palabras innecesarias (vacías de significado),
como "un", "y", "es" o "el", se pasan por alto. Por ejemplo, especificar
la frase "los productos pedidos durante estos meses de verano" es
lo mismo que especificar la frase "productos pedidos durante meses
verano". Se devuelven las filas que contengan alguna de las cadenas.
En el directorio \Mssql7\Ftdata\Sqlserver\Config se proporcionan
listas de palabras que no son relevantes en las búsquedas de muchos
idiomas. Este directorio se crea, y los archivos de palabras no
relevantes se instalan, cuando se instala Microsoft® SQL ServerT
con la funcionalidad de búsqueda de texto. Los archivos de palabras
no relevantes se pueden modificar. Por ejemplo, los administradores
del sistema de las empresas de alta tecnología podrían agregar la
palabra "sistema" a su lista de palabras no relevantes. (Si modifica
un archivo de palabras no relevantes, debe volver a rellenar los
catálogos de texto para que los cambios surtan efecto). Consulte
la ayuda de SQL-SERVER para conocer los correspondientes ficheros.
Cuando se procesa una consulta de texto, el motor de búsqueda devuelve
a Microsoft SQL Server los valores de clave de las filas que coinciden
con los criterios de búsqueda. Imagine una tabla CienciaFicción
en la que la columna NúmLibro es la columna de clave principal:
|
NúmLibro
|
Escritor
|
Título
|
| A025 |
Asimov |
Los límites de la fundación |
| A027 |
Asimov |
Fundación e imperio |
| C011 |
Clarke |
El fin de la infancia |
| V109 |
Verne |
La isla misteriosa |
Suponga que desea usar una consulta de recuperación de texto para
buscar los títulos de los libros que incluyen la palabra Fundación.
En este caso, del índice de texto se obtienen los valores A025 y A027.
SQL Server usa, a continuación, estas claves y el resto de la información
de los campos para responder a la consulta.
Componentes de las consultas de texto de Transact-SQL
Microsoft® SQL ServerT proporciona estos componentes
de Transact-SQL para las consultas de texto:
Predicados de Transact-SQL:
Los predicados CONTAINS y FREETEXT se pueden usar
en cualquier condición de búsqueda (incluida una cláusula WHERE)
de una instrucción SELECT.
Funciones de conjuntos de filas de Transact-SQL:
- CONTAINSTABLE
- FREETEXTTABLE
Las funciones CONTAINSTABLE y FREETEXTTABLE se pueden
usar en la cláusula FROM de una instrucción SELECT.
Propiedades de texto de Transact-SQL:
Éstas son algunas de las propiedades que se usan con las consultas
de texto y las funciones que se utilizan para obtenerlas:
- La propiedad IsFullTextEnabled indica si una base
de datos está habilitada para texto y se encuentra disponible
mediante la función DatabaseProperty.
- La propiedad TableHasActiveFulltextIndex indica
si una tabla está habilitada para texto y se encuentra disponible
mediante la función ObjectProperty.
- La propiedad IsFullTextIndexed indica si una columna
está habilitada para texto y se encuentra disponible mediante
la función ColumnProperty.
- La propiedad TableFullTextKeyColumn proporciona
el identificador de la columna de clave exclusiva de texto y se
encuentra disponible mediante la función ObjectProperty.
Procedimientos de texto almacenados del
sistema de Transact-SQL:
- Los procedimientos almacenados que definen los
índices de texto e inician el relleno de los índices de texto,
como, por ejemplo, sp_fulltext_catalog, sp_fulltext_table y sp_fulltext_column.
- Los procedimientos almacenados que consultan los
metadatos de los índices de texto que se han definido mediante
los procedimientos almacenados del sistema mencionados anteriormente,
como, por ejemplo, sp_help_fulltext_catalogs, sp_help_fulltext_tables,
sp_help_fulltext_columns, y una variación de éstos que permite
utilizar cursores sobre los conjuntos de resultados devueltos.
Estos procedimientos almacenados se pueden usar
en conjunción con la escritura de una consulta. Por ejemplo, puede
usarlos para buscar los nombres de las columnas indizadas de texto
de una tabla y el identificador de una columna de clave única de
texto antes de especificar una consulta.
Funciones de conjunto de filas CONTAINSTABLE y FREETEXTTABLE
Las funciones CONTAINSTABLE y FREETEXTTABLE se usan
para especificar las consultas de texto que devuelve la clasificación
por porcentaje de aciertos de cada fila. Estas funciones son muy
similares a los predicados de texto CONTAINS y FREETEXT, pero se
utilizan de forma diferente.
Aunque tanto los predicados de texto como las funciones de conjunto
de filas de texto se usan para las consultas de texto y la instrucción
TRANSACT-SQL usada para especificar la condición de búsqueda de
texto es la misma en los predicados y en las funciones, hay importantes
diferencias en la forma en la que éstas se usan:
CONTAINS y FREETEXT devuelven ambos el valor TRUE o FALSE,
con lo que normalmente se especifican en la cláusula WHERE de una
instrucción SELECT. Sólo se pueden usar para especificar los criterios
de selección, que usa Microsoft® SQL SERVER para determinar la pertenencia
al conjunto de resultados.
CONTAINSTABLE y FREETEXTTABLE devuelven ambas una tabla de
cero, una o más filas, con lo que deben especificarse siempre en
la cláusula FROM.Se usan también para especificar los criterios
de selección. La tabla devuelta tiene una columna llamada KEY que
contiene valores de claves de texto. Cada tabla de texto registrada
tiene una columna cuyos valores se garantizan como únicos. Los valores
devueltos en la columna KEY de CONTAINSTABLE o FREETEXTTABLE son
los valores únicos, procedentes de la tabla de texto registrada,
de las filas que coinciden con los criterios de selección en la
condición de búsqueda de texto.
Además, la tabla que producen CONTAINSTABLE y FREETEXTTABLE tiene
una columna denominada RANK, que contiene valores de 0 a 1000. Estos
valores se utilizan para ordenar las filas devueltas de acuerdo
al nivel de coincidencia con los criterios de selección.
Las consultas que usan las funciones CONTAINSTABLE y FREETEXTTABLE
son más complejas que las que usan los predicados CONTAINS y FREETEXT
porque las filas que cumplen los criterios y que son devueltas por
las funciones deben ser combinadas explícitamente con las filas
de la tabla original de SQL SERVER.
CONTAINSTABLE (T-SQL)
Devuelve una tabla con cero, una o más filas para
aquellas columnas de tipos de datos carácter que contengan palabras
o frases en forma precisa o "aproximada" (menos precisa), la proximidad
de palabras medida como distancia entre ellas, o coincidencias medidas.
A CONTAINSTABLE se le puede hacer referencia en una cláusula FROM
de una instrucción SELECT como si fuera un nombre de tabla normal.
Las consultas que utilizan CONTAINSTABLE especifican consultas de
texto contenido que devuelven un valor de distancia (RANK) por cada
fila. La función CONTAINSTABLE utiliza las mismas condiciones de
búsqueda que el predicado CONTAINS.
Sintaxis
CONTAINSTABLE (tabla, {columna | *}, '<condiciónBúsquedaContenido>')
<condiciónBúsqueda> ::=
{
| <términoGeneración>
| <términoPrefijo>
| <términoProximidad>
| <términoSimple>
| <términoPeso>
}
| { (<condiciónBúsqueda>)
{AND | AND NOT | OR} <condiciónBúsqueda> [...n]
}
<términoPeso> ::=
ISABOUT
( { {
<términoGeneración>)
| <términoPrefijo>)
| <términoProximidad>)
| <términoSimple>)
}
[WEIGHT (valorPeso)]
} [,...n]
)
<términoGeneración> ::=
FORMSOF (INFLECTIONAL, <términoSimple> [,...n] )
<términoPrefijo> ::=
{ "palabra * " | "frase * " }
<términoProximidad> ::=
{<términoSimple> | <términoPrefijo>}
{ {NEAR | ~} {<términoSimple> | <términoPrefijo>} } [.n]
<términoSimple> ::=
palabra | " frase "
Argumentos
tabla
Es el nombre de la tabla que ha sido registrada para búsquedas de
texto. tabla puede ser el nombre de un objeto de una base de datos
de una sola parte o el nombre de un objeto de una base de datos
con varias partes. Para obtener más información, consulte Convenciones
de sintaxis de Transact-SQL.
columna Es el nombre de la columna que se va a examinar,
que reside en tabla. Las columnas de tipos de datos de cadena de
caracteres son columnas válidas para búsquedas de texto.
*
Especifica que todas las columnas de la tabla que se hayan registrado
para búsquedas de texto se deben utilizar en las condiciones de
búsqueda.
<condiciónBúsqueda>
Especifica el texto que se va a buscar en columna. En la condición
de búsqueda no se puede utilizar variables.
palabra
Es una cadena de caracteres sin espacios ni signos de puntuación.
frase
Es una o varias palabras con espacios entre cada una de ellas.
-
- Nota Algunos idiomas, como los orientales, pueden
tener frases que contengan una o varias palabras sin espacios
entre ellas.
<términoPeso>
Especifica que las filas coincidentes (devueltas por la consulta)
coincidan con una lista de palabras y frases a las que se asigna
opcionalmente un valor de peso.
ISABOUT
Especifica la palabra clave <términoPeso>.
WEIGHT (valorPeso)
Especifica el valor de peso como número entre 0,0 y 1,0. Cada componente
de <términoPeso> puede incluir un valorPeso. valorPeso es
una forma de modificar cómo varias partes de una consulta afectan
al valor de distancia asignado a cada fila de la consulta. El peso
hace una medida diferente de la distancia de un valor porque todos
los componentes de <términoPeso> se utilizan para determinar
la coincidencia. Se devuelven las filas que contengan una coincidencia
con cualquiera de los parámetros ISABOUT, aunque no tengan un peso
asignado.
AND | AND NOT | OR
Especifica una operación lógica entre dos condiciones de búsqueda.
Cuando <condiciónBúsqueda> contiene grupos entre paréntesis,
dichos grupos entre paréntesis se evalúan primero. Después de evaluar
los grupos entre paréntesis, se aplican las reglas siguientes cuando
se utilizan estos operadores lógicos con condiciones de búsqueda:
- NOT se aplica antes que AND.
- NOT sólo puede estar a continuación de AND, como
en AND NOT. No se acepta el operador OR NOT. No se puede especificar
NOT antes del primer término (por ejemplo, CONTAINS(mycolumn,
'NOT "fraseBuscada" ' ).
- AND se aplica antes que OR.
- Los operadores booleanos del mismo tipo (AND,
OR) son asociativos y, por tanto, se pueden aplicar en cualquier
orden.
<términoGeneración>
Especifica la coincidencia de palabras cuando los términos simples
incluyen variaciones de la palabra original que se busca.
INFLECTIONAL
Especifica que se acepten las coincidencias de las formas plurales
y singulares de los nombres y los distintos tiempos verbales. Un
<términoSimple> dado dentro de un <términoGeneración>
no coincide con nombres y verbos a la vez.
<términoPrefijo>
Especifica la coincidencia de palabras o frases que comiencen con
el texto especificado. Enmarque el prefijo entre comillas dobles
("") y un asterisco (*) antes de la segunda comilla doble. Coincide
todo el texto que comience por el término simple especificado antes
del asterisco. El asterisco representa cero, uno o varios caracteres
(de la palabra o palabras raíz de la palabra o la frase). Cuando
<términoPrefijo> es una frase, todas las palabras de dicha
frase se consideran prefijos. Por tanto, una consulta que especifique
el prefijo "local wine *" hace que se devuelvan todas las filas
que contengan el texto "local winery", "locally wined and dined",
etc.
<términoProximidad>
Especifica la coincidencia de palabras o frases que estén cercanas
entre ellas. <términoProximidad> opera de forma similar al
operador AND: ambos requieren que existan varias palabras o frases
en la columna examinada. Cuanto más próximas estén las palabras
de <términoProximidad>, mejor será la coincidencia.
NEAR | ~
Indica que la palabra o frase del lado izquierdo del operador NEAR
o ~ tiene que estar bastante cerca de la palabra o frase del lado
derecho del operador NEAR o ~. Se pueden encadenar varios términos
de proximidad, por ejemplo:
-
-
a NEAR b NEAR c
Esto significa que la palabra o frase a tiene que
estar cerca de la palabra o frase b, que, a su vez, tiene que estar
cerca de la palabra o frase c.
Microsoft® SQL ServerT mide la distancia entre la palabra o frase
izquierda y derecha. Un valor de distancia bajo (por ejemplo, 0)
indica una distancia grande entre las dos. Si las palabras o frases
especificadas están lejos unas de las otras, satisfacen la condición
de la consulta; sin embargo, la consulta tiene un valor de distancia
muy bajo (0). Sin embargo, si <condiciónBúsqueda> sólo consta
de uno o varios términos de proximidad NEAR, SQL Server no devuelve
filas con un valor de distancia de 0.
<términoSimple>
Especifica la coincidencia con una palabra exacta (uno o varios
caracteres sin espacios o signos de puntuación en idiomas con caracteres
de un solo byte) o una frase (una o varias palabras consecutivas
separadas por espacios y signos de puntuación opcionales en idiomas
con caracteres de un solo byte). Ejemplos de términos simples válidos
son "blue berry", blueberry y "Microsoft SQL Server". Las frases
tienen que ir entre comillas dobles (""). Las palabras de una frase
tienen que aparecer en la columna de la base de datos en el mismo
orden que el especificado en <condiciónBúsqueda>. La búsqueda
de caracteres en la palabra o la frase distingue entre mayúsculas
y minúsculas. Las palabras de una sola sílaba (como un, y, la) de
las columnas de texto indizadas no se almacenan en los índices de
los textos. Si únicamente se utiliza una de estas palabras en una
búsqueda, SQL Server devuelve un mensaje de error indicando que
en la consulta sólo hay monosílabos. SQL Server incluye una lista
estándar de palabras monosílabas en el directorio \Mssql7\Ftdata\Sqlserver\Config.
Los signos de puntuación se omiten. Por lo tanto, el valor "¿Dónde
está mi equipo? satisface la condición CONTAINS(testing, "fallo
del equipo") El fallo de la búsqueda sería grave.".
n
Es un marcador de posición que indica que se pueden especificar
varias condiciones y términos de búsqueda.
Observaciones
CONTAINS no se reconoce como palabra
clave si el nivel de compatibilidad es menor de 70. Para obtener
más información, consulte sp_dbcmptlevel.
La tabla devuelta por la funcion CONTAINSTABLE tiene una columna
llamada KEY que contiene valores de claves de texto. Todas las tablas
con textos indizados tienen una columna cuyos valores se garantizan
que son únicos y los valores devueltos en la columna KEY son los
valores de claves de textos de las filas que satisfacen los criterios
de selección especificados en la condición de búsqueda. La propiedad
TableFulltextKeyColumn, obtenida mediante la función OBJECTPROPERTY,
proporciona la identidad de esta columna de clave única. Para obtener
las filas de la tabla original que desee, especifique una combinación
con las filas de CONTAINSTABLE. La forma típica de la cláusula FROM
de una instrucción SELECT que utilice CONTAINSTABLE es:
SELECT select_list
FROM table AS FT_TBL INNER JOIN
CONTAINSTABLE(table, column, contains_search_condition) AS KEY_TBL
ON FT_TBL.unique_key_column = KEY_TBL.[KEY]
La tabla que produce CONTAINSTABLE incluye una columna llamada RANK.
La columna RANK es un valor (entre 0 y 1000) que para cada fila
indica lo bien que cada una de ellas satisface los criterios de
selección. Este valor de distancia se suele utilizar en las instrucciones
SELECT de una de estas maneras:
- En la cláusula ORDER BY, para devolver las filas
de mayor valor al principio.
- En la lista de selección, para ver el valor de
distancia asignado a cada fila.
- En la cláusula WHERE, para filtrar las filas con
valores de distancia bajos.
CONTAINSTABLE no se reconoce como palabra clave
si el nivel de compatibilidad es menor de 70. Para obtener más información,
consulte sp_dbcmptlevel.
Ejemplos
A. Devolver valores de distancia mediante CONTAINSTABLE
Este ejemplo busca todos los nombres de productos que contengan
las palabras "breads", "fish" o "beers", y los distintos pesos asignados
a cada palabra. Por cada fila devuelta que cumpla los criterios
de la búsqueda, se muestra la precisión relativa (valor de distancia)
de la coincidencia. Además, las filas de mayor valor de distancia
se devuelven primero.
USE Northwind
GO
SELECT FT_TBL.CategoryName, FT_TBL.Description, KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
CONTAINSTABLE(Categories, Description,
'ISABOUT (breads weight (.8),
fish weight (.4), beers weight (.2) )' ) AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC
GO
B. Devolver valores de distancia mayores que uno
especificado mediante CONTAINSTABLE
Este ejemplo devuelve la descripción y el nombre de la categoría
de todas las categorías de alimentos en las que la columna Description
contenga las palabras "sweet" y "savory" cerca de la palabra "sauces"
o de la palabra "candies". Todas las filas cuya categoría sea "Seafood"
no se devuelven. Sólo se devuelven las filas cuyo grado de coincidencia
sea igual o superior a 2.
USE Northwind
GO
SELECT FT_TBL.Description,
FT_TBL.CategoryName,
KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
CONTAINSTABLE (Categories, Description,
'("sweet and savory" NEAR sauces) OR
("sweet and savory" NEAR candies)'
) AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK > 2
AND FT_TBL.CategoryName <> 'Seafood'
ORDER BY KEY_TBL.RANK DESC
C. Utilizar CONTAINS con <términoSimple>
Este ejemplo busca todos los productos cuyo precio sea $15,00 que
contengan la palabra "bottles".
USE Northwind
GO
SELECT ProductName
FROM Products
WHERE UnitPrice = 15.00
AND CONTAINS(QuantityPerUnit, 'bottles')
GO
D. Utilizar CONTAINS y una frase en <términoSimple>
Este ejemplo devuelve todos los productos que contengan la frase
"sasquatch ale" o "steeleye stout".
USE Northwind
GO
SELECT ProductName
FROM Products
WHERE CONTAINS(ProductName, ' "Sasquatch ale" OR "steeleye stout"
')
GO
E. Utilizar CONTAINS con <términoPrefijo>
Este ejemplo devuelve todos los nombres de productos que tengan
al menos una palabra que empiece por el prefijo "choc" en la columna
ProductName.
USE Northwind
GO
SELECT ProductName
FROM Products
WHERE CONTAINS(ProductName, ' "choc*" ')
GO
F. Utilizar CONTAINS y OR con <términoPrefijo>
Este ejemplo devuelve todas las descripciones de categorías que
contengan las cadenas "sea" o "bread".
USE Northwind
SELECT CategoryName
FROM Categories
WHERE CONTAINS(Description, '"sea*" OR "bread*"')
GO
G. Utilizar CONTAINS con <términoProximidad>
Este ejemplo devuelve todos los nombres de los productos que tengan
la palabra "Boysenberry" cerca de la palabra "spread".
USE Northwind
GO
SELECT ProductName
FROM Products
WHERE CONTAINS(ProductName, 'spread NEAR Boysenberry')
GO
H. Utilizar CONTAINS con <términoGeneración>
Este ejemplo busca todos los productos que tengan palabras derivadas
de "dry": "dried", "drying", etc.
USE Northwind
GO
SELECT ProductName
FROM Products
WHERE CONTAINS(ProductName, ' FORMSOF (INFLECTIONAL, dry) ')
GO
I. Utilizar CONTAINS con <términoPeso>
Este ejemplo busca todos los nombres de productos que contengan
las palabras "spread", "sauces" o "relishes", y los distintos pesos
asignados a cada palabra.
USE Northwind
GO
SELECT CategoryName, Description
FROM Categories
WHERE CONTAINS(Description, 'ISABOUT (spread weight (.8),
sauces weight (.4), relishes weight (.2) )' )
GO
FREETEXTTABLE
Devuelve una tabla de cero, una o varias filas cuyas
columnas contienen datos de tipo carácter cuyos valores coinciden
con el significado, no literalmente, con el texto especificado en
cadenaTexto. Se puede hacer referencia a FREETEXTTABLE en las cláusula
FROM de las instrucciones SELECT como a otro nombre de tabla normal.
Las consultas que utilizan FREETEXTTABLE especifican consultas de
texto que devuelven el valor de coincidencia (RANK) de cada fila.
Sintaxis
FREETEXTTABLE (tabla, {columna | *}, 'cadenaTexto')
Argumentos
tabla
Es el nombre de la tabla que se ha marcado para búsquedas de texto.
tabla puede ser el nombre de un objeto de una base de datos de una
sola parte o el nombre de un objeto de una base de datos con varias
partes.
columna
Es el nombre de la columna de tabla en la que se va a buscar. Las
columnas cuyos datos sean del tipo de cadena de caracteres son columnas
válidas para buscar texto.
*
Especifica que todas las columnas que hayan sido registradas para
la búsqueda de texto se tienen que utilizar para buscar la cadenaTexto
dada.
cadenaTexto
Es el texto que se va a buscar en la columna especificada. No se
pueden utilizar variables.
Observaciones FREETEXTTABLE utiliza las mismas condiciones
de búsqueda que el predicado FREETEXT.Al igual que en CONTAINSTABLE,
la tabla devuelta tiene columnas llamadas KEY y RANK, a las que
se hace referencia en la consulta para obtener las filas apropiadas
y utilizar los valores de distancia.FREETEXTTABLE no se reconoce
como palabra clave si el nivel de compatibilidad es menor que 70.
Para obtener más información, consulte sp_dbcmptlevel.
Ejemplos
En este ejemplo se devuelve el nombre y la descripción
de todas las categorías relacionadas con "sweet", "candy", "bread",
"dry" y "meat".
USE Northwind
SELECT FT_TBL.CategoryName,
FT_TBL.Description,
KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
FREETEXTTABLE(Categories, Description,
'sweetest candy bread and dry meat') AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
GO
Utilizar el predicado CONTAINS
Puede usar el predicado CONTAINS para buscar una
determinada frase en una base de datos. Por supuesto, dicha consulta
puede escribirse con el predicado LIKE. Sin embargo, algunas formas
de CONTAINS proporcionan mayor variedad de consultas de texto que
la que se puede obtener con LIKE. Además, al contrario que cuando
se utiliza el predicado LIKE, una búsqueda con CONTAINS no distingue
entre mayúsculas y minúsculas.
Nota. Las consultas de búsqueda de texto se comportan de
forma que no distinguen entre mayúsculas y minúsculas en aquellos
idiomas (mayoritariamente los latinos) en los que tiene sentido
distinguir entre mayúsculas y minúsculas. Sin embargo, en japonés,
hay muchas ortografías fonéticas en las que el concepto de normalización
ortográfica implica no distinguir las mayúsculas de las minúsculas
(por ejemplo, las letras kana no tienen mayúsculas y minúsculas).
Este tipo de normalización ortográfica no se admite.
Suponga que desea buscar en la base de datos Northwind la frase
"bean curd". Si usa el predicado CONTAINS, ésta es una consulta
bastante fácil.
USE Northwind USE Northwind
GO
SELECT Description
FROM Categories
WHERE Description LIKE '%bean curd%'
GO
O, con CONTAINS:
USE Northwind
GO
SELECT Description
FROM Categories
WHERE CONTAINS(Description, ' "bean curd" ')
GO
El predicado CONTAINS usa una notación funcional
en la que el primer parámetro es el nombre de la columna que se
está buscando y el segundo parámetro es una condición de búsqueda
de texto. La condición de búsqueda, en este caso "bean curd", puede
ser bastante compleja y está formada por uno o más elementos, que
se describen posteriormente.
El predicado CONTAINS admite una sintaxis compleja para buscar en
las columnas basadas en caracteres:
- Una o más palabras y frases específicas (términos
simples). Una palabra está compuesta por uno o más caracteres
sin espacios ni signos de puntuación. Una frase válida consta
de varias palabras con espacios y con o sin signos de puntuación
entre ellas. Por ejemplo, croissant es una palabra y café au lait
es una frase. Las palabras y frases como éstas se llaman términos
simples.
- Forma no flexionada de una palabra determinada
(término de generación). Por ejemplo, buscar la forma no flexionada
de la palabra "conducir". Si hay varias filas en la tabla que
incluyen las palabras "conducir", "conduce", "condujo", "conduciendo"
y "conducido", todas estarían en el conjunto de resultados porque
cada una de estas palabras se puede generar de forma inflexiva
a partir de la palabra "conducir".
- Una palabra o frase en la que las palabras empiezan
con un texto determinado (término prefijo). En el caso de una
frase, cada palabra de la frase se considera un prefijo. Por ejemplo,
el término "tran* auto" coincide con "transmisión automática"
y "transductor de automóvil".
- Palabras o frases que usan valores ponderados
(término ponderado). Por ejemplo, podría desear encontrar una
palabra que tuviera un peso designado superior a otra palabra.
Devuelve resultados de consulta clasificados.
- Una palabra o frase que esté cerca de otra palabra
o frase (término de proximidad). Por ejemplo, podría desear encontrar
las filas en las que la palabra "hielo" aparece cerca de la palabra
"hockey" o en las que la frase "patinaje sobre hielo" se encuentra
próxima a la frase "hockey sobre hielo".
Un predicado CONTAINS puede combinar varios de estos
términos si usa AND y OR, por ejemplo, podría buscar todas las filas
con "leche" y "café al estilo de Toledo" en la misma columna de
base datos habilitada para texto . Además, los términos se pueden
negar con el uso de AND NOT, por ejemplo, "pastel AND NOT queso
de untar".
Cuando use CONTAINS, recuerde que SQL Server rechaza las palabras
vacías de los criterios de búsqueda. Las palabras irrelevantes son
aquellas como "un", "y", "es" o "el", que aparecen con frecuencia
pero que, en realidad, no ayudan en la búsqueda de un texto determinado.
Utilizar el predicado FREETEXT
Con un predicado FREETEXT, puede escribir cualquier
conjunto de palabras o frases, e incluso una frase completa. El
motor de consultas de texto examina este texto, identifica todas
las palabras y frases de nombres significativas y construye internamente
una consulta con esos términos. En este ejemplo se usa un predicado
FREETEXT en una columna llamada description.
FREETEXT (description, ' "The Fulton
County Grand Jury said Friday an investigation of Atlanta's recent
primary election produced no evidence that any irregularities took
place." ')
El motor de búsqueda identifica palabras y frases
nominales tales como las siguientes:
- Palabras:
- Fulton, county, grand, jury, Friday, investigation,
Atlanta, recent, primary, election, produce, evidence, irregularities
- Frases:
- Fulton county grand jury, primary election, grand
jury, Atlanta's recent primary election
Las palabras y frases de la cadena FREETEXT (y sus
variaciones generadas de forma inflexiva) se combinan internamente
en una consulta, ponderada para clasificarla adecuadamente y, a
continuación, se realiza la búsqueda real.
Funciones de conjunto de filas CONTAINSTABLE y FREETEXTTABLE
Las funciones CONTAINSTABLE y FREETEXTTABLE se usan
para especificar las consultas de texto que devuelve la clasificación
por porcentaje de aciertos de cada fila. Estas funciones son muy
similares a los predicados de texto CONTAINS y FREETEXT, pero se
utilizan de forma diferente.
Los predicados de texto de las funciones
Aunque tanto los predicados de texto como las funciones
de conjunto de filas de texto se usan para las consultas de texto
y la instrucción TRANSACT-SQL usada para especificar la condición
de búsqueda de texto es la misma en los predicados y en las funciones,
hay importantes diferencias en la forma en la que éstas se usan:
- CONTAINS y FREETEXT devuelven ambos el valor TRUE
o FALSE, con lo que normalmente se especifican en la cláusula
WHERE de una instrucción SELECT.
CONTAINSTABLE y FREETEXTTABLE devuelven ambas una tabla de cero,
una o más filas, con lo que deben especificarse siempre en la
cláusula FROM.
- CONTAINS y FREETEXT sólo se pueden usar para especificar
los criterios de selección, que usa Microsoft® SQL SERVER para
determinar la pertenencia al conjunto de resultados.
CONTAINSTABLE y FREETEXTTABLE se usan también para especificar
los criterios de selección. La tabla devuelta tiene una columna
llamada KEY que contiene valores de claves de texto. Cada tabla
de texto registrada tiene una columna cuyos valores se garantizan
como únicos. Los valores devueltos en la columna KEY de CONTAINSTABLE
o FREETEXTTABLE son los valores únicos, procedentes de la tabla
de texto registrada, de las filas que coinciden con los criterios
de selección en la condición de búsqueda de texto.
Además, la tabla que producen CONTAINSTABLE y FREETEXTTABLE tiene
una columna denominada RANK, que contiene valores de 0 a 1000.
Estos valores se utilizan para ordenar las filas devueltas de
acuerdo al nivel de coincidencia con los criterios de selección.
Las consultas que usan las funciones CONTAINSTABLE
y FREETEXTTABLE son más complejas que las que usan los predicados
CONTAINS y FREETEXT porque las filas que cumplen los criterios y
que son devueltas por las funciones deben ser combinadas explícitamente
con las filas de la tabla original de SQL SERVER.
Este ejemplo devuelve la descripción y el nombre de categoría de
todas las categorías de alimentos en las que la columna Description
contenga las palabras "sweet and savory" cerca de la palabra "sauces"
o de la palabra "candies". Todas las filas cuyo nombre de categoría
sea "Seafood" no se devuelven. Sólo se devuelven las filas cuyo
valor de distancia sea igual o superior a 2.
USE Northwind
GO
SELECT FT_TBL.Description, FT_TBL.CategoryName, KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
CONTAINSTABLE (Categories, Description,
'("sweet and savory" NEAR sauces) OR
("sweet and savory" NEAR candies)') AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK > 2 AND FT_TBL.CategoryName <> 'Seafood'
ORDER BY KEY_TBL.RANK DESC
Este ejemplo devuelve la descripción y el nombre
de categoría de las 10 categorías superiores de alimentos donde
la columna Description contenga las palabras "sweet and savory"
cerca de la palabra "sauces" o de la palabra "candies".
SELECT FT_TBL.Description, FT_TBL.CategoryName,
KEY_TBL.RANK
FROM Categories AS FT_TBL INNER JOIN
CONTAINSTABLE (Categories, Description,
'("sweet and savory" NEAR sauces) OR
("sweet and savory" NEAR candies)', 10) AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
Comparación entre CONTAINSTABLE y CONTAINS
La función CONTAINSTABLE y el predicado CONTAINS
utilizan condiciones de búsqueda similares.
Sin embargo, en CONTAINSTABLE se especifica la tabla en la que tendrá
lugar la búsqueda de texto, la columna (o todas las columnas) de
la tabla en las que se buscará y la condición de búsqueda. Un cuarto
parámetro, opcional, hace posible que el usuario indique que se
devuelva sólo el número más alto especificado de coincidencias.
Para obtener más información, consulte la sección Limitar los conjuntos
de resultados.
CONTAINSTABLE devuelve una tabla que incluye una columna denominada
RANK. Esta columna RANK contiene un valor para cada fila que indica
el grado de coincidencia de cada fila con los criterios de selección.
En esta consulta se especifica la utilización de CONTAINSTABLE para
devolver un valor de clasificación por cada fila.
USE Northwind
GO
SELECT K.RANK, CompanyName, ContactName, Address
FROM Customers AS C
INNER JOIN
CONTAINSTABLE(Customers,Address,
'ISABOUT ("des*", Rue WEIGHT(0.5), Bouchers WEIGHT(0.9))') AS K
ON C.CustomerID = K.[KEY]
Comparación entre FREETEXTTABLE y FREETEXT
En la consulta siguiente se amplía una consulta FREETEXTTABLE
para que devuelva primero las filas con clasificación superior y
agregue la clasificación de cada fila a la lista de selección. Para
especificar la consulta, debe saber que CategoryID es la columna
de clave única de la tabla Categories.
USE Northwind
GO
SELECT KEY_TBL.RANK, FT_TBL.Description
FROM Categories AS FT_TBL
INNER JOIN
FREETEXTTABLE(Categories, Description,
'How can I make my own beers and ales?') AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
ORDER BY KEY_TBL.RANK DESC
GO
La única diferencia en la sintaxis de FREETEXTTABLE
y FREETEXT es la inserción del nombre de la tabla como el primer
parámetro.
Esto es una ampliación de la misma consulta que sólo devuelve las
filas con un valor de clasificación de 10 o superior:
USE Northwind
GO
SELECT KEY_TBL.RANK, FT_TBL.Description
FROM Categories FT_TBL
INNER JOIN
FREETEXTTABLE (Categories, Description,
'How can I make my own beers and ales?') AS KEY_TBL
ON FT_TBL.CategoryID = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK >= 10
ORDER BY KEY_TBL.RANK DESC
GO
Identificación del nombre de la columna de la clave
única
Las consultas que usan funciones que toman valores
de conjuntos de filas son complicadas porque es necesario saber
el nombre de la columna de clave exclusiva. Cada tabla habilitada
para texto tiene la propiedad TableFulltextKeyColumn que contiene
el número de ID de la columna que ha sido seleccionada para tener
filas únicas en la tabla. En este ejemplo se muestra cómo se puede
obtener el nombre de la columna de clave y usarse en la programación.
USE Northwind
GO
DECLARE @key_column sysname
SET @key_column = Col_Name(Object_Id('Categories'),
ObjectProperty(Object_id('Categories'),
'TableFulltextKeyColumn')
)
print @key_column
EXECUTE ('SELECT Description, KEY_TBL.RANK
FROM Categories FT_TBL
INNER JOIN
FreetextTable (Categories, Description,
''How can I make my own beers and ales?'') AS KEY_TBL
ON FT_TBL.'
+ @key_column
+' = KEY_TBL.[KEY]
WHERE KEY_TBL.RANK >= 10
ORDER BY KEY_TBL.RANK DESC
')
GO
Puede evitar la complejidad de la utilización de
CONTAINSTABLE y FREETEXTTABLE si escribe procedimientos almacenados
que acepten unos cuantos supuestos acerca de la consulta y, a continuación,
creen y ejecuten la consulta adecuada. A continuación se muestra
un procedimiento simplificado que emite una consulta FREETEXTTABLE.
La tabla muestra los parámetros del procedimiento (todas las entradas).
| Parámetros |
Opcional |
Descripción |
| @additional_predicates |
Opcional |
Si hay algún predicado adicional, éste se agrega
con AND detrás del predicado FREETEXT. KEY_TBL.RANK se puede
usar en expresiones. |
| @freetext_column |
SI |
|
| @freetext_search |
SI |
Condición de Búsqueda |
| @from_table |
SI |
|
| @order_by_list |
Opcional |
KEY_TBL.RANK puede ser una de las columnas especificadas. |
| @select_list |
SI |
KEY_TBL.RANK puede ser una de las columnas especificadas. |
El código del procedimiento es el siguiente:
CREATE PROCEDURE freetext_rank_proc
@select_list nvarchar(1000),
@from_table nvarchar(517),
@freetext_column sysname,
@freetext_search nvarchar(1000),
@additional_predicates nvarchar(500) = '',
@order_by_list nvarchar(500) = ''
AS
BEGIN
DECLARE @table_id integer,
@unique_key_col_name sysname,
@add_pred_var nvarchar(510),
@order_by_var nvarchar(510)
-- Get the name of the unique key column for this table.
SET @table_id = Object_Id(@from_table)
SET @unique_key_col_name =
Col_Name( @table_id,
ObjectProperty(@table_id, 'TableFullTextKeyColumn') )
-- If there is an additional_predicate, put AND() around it.
IF @additional_predicates <> ''
SET @add_pred_var = 'AND (' + @additional_predicates + ')'
ELSE
SET @add_pred_var = ''
-- Insert ORDER BY, if needed.
IF @order_by_list <> ''
SET @order_by_var = 'ORDER BY ' + @order_by_var
ELSE
SET @order_by_var = ''
-- Execute the SELECT statement.
EXECUTE ( 'SELECT '
+ @select_list
+ ' FROM '
+ @from_table
+ ' AS FT_TBL, FreetextTable('
+ @from_table
+ ','
+ @freetext_column
+ ','''
+ @freetext_search
+ ''') AS KEY_TBL '
+ 'WHERE FT_TBL.'
+ @unique_key_col_name
+ ' = KEY_TBL.[KEY] '
+ @add_pred_var
+ ' '
+ @order_by_var
)
END
Este procedimiento se puede usar para emitir la
consulta:
USE Northwind
GO
EXECUTE freetext_rank_proc
'Description, KEY_TBL.RANK', -- Select list
'Categories', -- From
'Description', -- Column
'How can I make my own beers and ales?', -- Freetext search
'KEY_TBL.RANK >= 10', -- Additional predicate
'KEY_TBL.RANK DESC' -- Order by
GO
Limitar los conjuntos de resultados
En muchas consultas de texto, el número de elementos
que coinciden con la condición de búsqueda es muy grande. Para evitar
que las consultas devuelvan demasiadas coincidencias, utilice el
argumento opcional, top_n_by_rank, en CONTAINSTABLE y FREETEXTTABLE
para especificar el número de coincidencias, ordenadas, que desea
que se devuelvan.
Con esta información, Microsoft® SQL SERVER ordena las coincidencias
y devuelve sólo hasta completar el número especificado. Esta opción
puede aumentar significativamente el rendimiento. Por ejemplo, una
consulta que por lo general devolvería 100.000 filas de una tabla
de 1 millón se procesará de forma más rápida si sólo se piden las
100 primeras filas.
Si sólo se desea que se devuelvan las 3 coincidencias mayores del
ejemplo anterior, mediante CONTAINSTABLE, la consulta tendrá esta
forma:
USE Northwind
GO
SELECT K.RANK, CompanyName, ContactName, Address
FROM Customers AS C
INNER JOIN
CONTAINSTABLE(Customers,Address, 'ISABOUT ("des*",
Rue WEIGHT(0.5),
Bouchers WEIGHT(0.9))', 3) AS K
ON C.CustomerID = K.[KEY]
Buscar palabras o frases con valores ponderados
(término ponderado)
Puede buscar palabras o frases y especificar un valor
ponderado. El peso, un número entre 0,0 y 1,0, indica el grado de
importancia de cada palabra o frase en un conjunto de palabras y
frases. El valor 0,0 es el peso más pequeño disponible, y el valor
1,0 es el peso más grande. Por ejemplo, en esta consulta se buscan
todas las direcciones de los clientes, con valores ponderados, en
los que cualquier texto que comience con la cadena "des" esté cerca
de Rue o Bouchers. Microsoft® SQL SERVERT da una clasificación superior
a aquellas filas que contienen la mayor cantidad de palabras especificadas.
Por tanto, SQL SERVER da una clasificación superior a una fila que
contiene des Rue Bouchers que a una fila que contiene des Rue.
USE Northwind
GO
SELECT CompanyName, ContactName, Address
FROM Customers
WHERE CONTAINS(Address, 'ISABOUT ("*des*",
Rue WEIGHT(0.5),
Bouchers WEIGHT(0.9)
) ' )
GO
Un término ponderado se puede usar en conjunción
con cualquiera de los otros cuatro tipos de términos.
Combinar predicados de texto con otros predicados
de TRANSACT-SQL
Los predicados CONTAINS y FREETEXT se pueden combinar
con el resto de predicados de TRANSACT-SQL, como, por ejemplo, LIKE
y BETWEEN; también se pueden usar en una subconsulta. En este ejemplo
se buscan descripciones cuya categoría no sea Seafood y que contengan
la palabra "sauces" y la palabra "seasonings".
USE Northwind
GO
SELECT Description
FROM Categories
WHERE CategoryName <> 'Seafood' AND
CONTAINS(Description, ' sauces AND seasonings ')
GO
En la siguiente consulta se usa CONTAINS dentro
de una subconsulta. Con la base de datos pubs, la consulta obtiene
el valor del título de todos los libros de la tabla titles del publicador
que se encuentra próximo al platillo volante de Moonbeam, Ontario.
(Esta información acerca del publicador se encuentra en la columna
pr_info de la tabla pub_info y sólo hay uno de estos publicadores.)
USE pubs
GO
-- Add some interesting rows to some tables.
INSERT INTO publishers
VALUES ('9970', 'Penumbra Press', 'Moonbeam', 'ON', 'Canada')
INSERT INTO pub_info (pub_id, pr_info)
VALUES ('9970',
'Penumbra press is located in the small village of Moonbeam. Moonbeam
is well known as the flying saucer capital of Ontario. You will often
find one or more flying saucers docked close to the tourist information
centre on the north side of highway 11.')
INSERT INTO titles
VALUES ('FP0001', 'Games of the World', 'crafts', '9970', 9.85,
0.00, 20, 213, 'A crafts book! A sports book! A history book! The
fun and excitement of a world at play -
beautifully described and lavishly illustrated', '1977/09/15')
GO
-- Given the full-text catalog for these tables is pubs_ft_ctlg,
-- repopulate it so new rows are included in the full-text indexes.
sp_fulltext_catalog 'pubs_ft_ctlg', 'start_full'
WAITFOR DELAY '00:00:30' -- Wait 30 seconds for population.
GO
-- Issue the query.
SELECT T.title, P.pub_name
FROM publishers P,
titles T
WHERE P.pub_id = T.pub_id
AND P.pub_id = (SELECT pub_id
FROM pub_info
WHERE CONTAINS (pr_info,
' moonbeam AND
ontario AND
"flying saucer" '))
GO
Utilizar predicados de texto para consultar columnas
de tipo IMAGE
Los predicados CONTAINS y FREETEXT pueden utilizarse
para buscar columnas IMAGE indizadas.
En una sola columna IMAGE es posible almacenar muchos tipos de documentos.
Microsoft® SQL SERVERT admite ciertos tipos de documento y proporciona
filtros para los mismos. Esta versión proporciona filtros para documentos
de Office, archivos de texto y archivos HTML.
Cuando una columna IMAGE participa en un índice de texto, el servicio
de texto comprueba las extensiones de los documentos de la columna
IMAGE y aplica el filtro correspondiente, para interpretar los datos
binarios y extraer la información de texto necesaria para la indización
y la consulta.
Así, cuando configure la indización de texto sobre una columna IMAGE
de una tabla, deberá crear una columna separada para que contenga
la información relativa al documento. Esta columna de tipo debe
ser de cualquier tipo de datos basado en caracteres y contendrá
la extensión del archivo, como por ejemplo DOC para los documentos
de Microsoft Word. Si el tipo de columna es NULL, el servicio de
texto asumirá que el documento es un archivo de texto.
- En el Asistente para indización de texto, si selecciona
una columna IMAGE para la indización, deberá especificar también
una Columna de enlace para que contenga el tipo de documento.
- El procedimiento almacenado sp_fulltext_column
acepta también un argumento para la columna que contendrá los
tipos de documento.
- El procedimiento almacenado sp_help_fulltext_columns
devuelve también el nombre de columna y el Id. de columna de la
columna de tipo de documento.