2008-11-19 14 views
7

Siempre que escribo un procedimiento almacenado para seleccionar datos basado en una variable de cadena (varchar, nvarchar, char) Me gustaría tener algo como:Al igual que frente a "=" para hacer coincidir cadenas utilizando SQL Server

procedure dbo.p_get_user_by_username(
    @username  nvarchar(256) 
as 
begin 
    select 
     u.username 
     ,u.email 
     --,etc 
    from 
     sampleUserTable u 
    where 
     u.username = @username 
end 

Así que en es decir, para igualar el récord que tendría

u.username = @username 

Pero a veces encontrar código que utilizaría LIK E en lugar de =

u.username like(@username) 

¿Cuándo utilizarlo? ¿No debería usarse solo cuando necesita una coincidencia de comodín?

EDITAR

Gracias por las respuestas.

Creo que necesito aclarar que lo que realmente estaba tratando de preguntar era: si pudiera haber una situación en la que se prefiriera usar como en lugar de "=" para una coincidencia exacta de cadenas. De las respuestas podría decir que no habría. Desde mi propia experiencia, incluso en situaciones en las que necesito ignorar, por ejemplo, casos y espacios iniciales y finales, usaría ltrim, rtrim, menor en ambas cadenas y luego "=". Gracias de nuevo por tu aportación.

+0

Este código tal como está es realmente arriesgado con una cláusula similar que no se está escapando ... significa que si tiene un nombre de usuario llamado 'bob_dylan' se tratará igual que 'bobXdylan'. necesitas escapar aquí para la cláusula similar. –

+0

Además, si alguien pasa un nombre de usuario de decir '%' forzará un escaneo de tabla en su tabla de usuario Y devolverá todos los usuarios ... –

+0

Gracias, sambo esos son algunos puntos buenos, era consciente del peligro de pasar ' % 'y no estaba familiarizado con el problema de escape anteriormente. Lo que realmente estaba tratando de preguntar es si alguien alguna vez usaría en lugar de "=" para una cadena exacta que coincida con – kristof

Respuesta

13

Estás en la correcta. No hay beneficio en usar LIKE a menos que esté haciendo una coincidencia comodín. Además, usarlo sin comodín podría llevar al uso de un plan de consulta ineficiente.

+0

Esto no es correcto, el optimizador funcionará bien con declaraciones like en campos indexados , es solo cuando tienes comodines que tienes que tener mucho cuidado. Por lo tanto, seleccione * de t donde el campo como '% anything' forzará un escaneo de tabla, pero como 'hello%' no lo hará (si está indexado) –

+0

Además, vea mi respuesta, como no coincidirá en los espacios finales en un out-of- la instalación de sql 2005 de la caja. –

2

Con la palabra clave LIKE puede hacer coincidir el campo u.username con un patrón específico en lugar de una "cadena" fija.

-1

Sí, hasta donde yo sé, usar como sin ningún comodín es lo mismo que usar el operador =. ¿Estás seguro de que el parámetro de entrada no tiene comodines?

1

Sí, tienes razón, solo se debe usar para coincidencia de comodines. Se debe usar con moderación, especialmente en tablas muy grandes en campos no indexados, ya que puede ralentizar sus consultas de forma MUY BAJA.

+0

No es realmente correcto hacer un like '% tail' forzará un análisis de índice/tabla, pero al igual que 'head%' funcionará bastante bien si el campo está indexado ... –

3

Si no se utilizan comodines, entonces la diferencia es, que "=" hace una coincidencia exacta, pero al igual que coincidirá con una cadena con espacios finales (de SSBO):

Al realizar las comparaciones de cadenas con LIKE, todos los caracteres en la cadena de patrón son significativos, incluyendo espacios iniciales o finales. Si una comparación en una consulta es devolver todas las filas con una cadena como 'abc' (abc seguido de un único espacio ), una fila en la que el valor de que la columna es ABC (abc sin un espacio ) no es devuelto Sin embargo, espacios en blanco al final, en la expresión a que coincide con el patrón, son ignorados.Si una comparación en una consulta es para devolver todas las filas con la cadena LIKE 'abc' (abc sin espacio), se devuelven todas las filas que comienzan con abc y tienen cero o más espacios en blanco al final.

+0

Buen punto. La forma ideal es recortar el nombre de usuario. – avgbody

+0

Curiosamente, este comportamiento solo es cierto en un campo Unicode. En un campo ANSI, LIKE no tiene en cuenta los espacios y se comportan de forma idéntica. Este es probablemente un error en MSSQL 2008. – Brain2000

2

Si está viendo esto en el código de otras personas, tal vez tengan la intención de permitir que una persona pase una cadena que incluye un patrón o comodines.

7

Sunny casi lo hizo bien :)

Ejecutar lo siguiente en control de calidad en una instalación predeterminada de SQL2005

select * from sysobjects where name = 'sysbinobjs ' 
-- returns 1 row 
select * from sysobjects where name like 'sysbinobjs ' 
-- returns 0 rows 

Así que, como no coincide con el espacio final, en el lado de plan de consulta ambos realizan casi por igual, pero la unión '=' funciona un poco mejor.

Una cosa adicional que DEBE tener en cuenta cuando use LIKE es escaparse de la cuerda correctamente.

declare @s varchar(40) 
set @s = 'escaped[_]_%' 

select 1 where 'escaped[_]_%' like @s 
--Return nothing = BAD 

set @s = '_e_s_c_a_p_e_d_[___]___%' 

select 1 where 'escaped[_]_%' like @s escape '_' 
--Returns 1 = GOOD 

En general las personas no utilizan como por la coincidencia exacta, porque los temas que escapan causan todo tipo de complicaciones y errores sutiles, la gente se olvida de escapar y hay un mundo de dolor.

Pero ... si quiere una coincidencia exacta real que sea eficiente, LIKE puede resolver el problema.

Digamos que desea hacer coincidir el nombre de usuario con "sam" y no desea obtener "Sam" o "Sam" y desafortunadamente la compilación de la columna no distingue entre mayúsculas y minúsculas.

Algo como lo siguiente (con el escape agregado) es el camino a seguir.

select * from sysobjects 
WHERE name = 'sysbinobjs' and name COLLATE Latin1_General_BIN LIKE 'sysbinobjs' 

La razón por la que hace una doble coincidencia es para evitar una exploración de tabla.

Sin embargo ....

creo que el varbinary casting trick es menos propenso a errores y fácil de recordar.

+0

gracias sambo (y upvote por supuesto) para obtener buenos puntos sobre el uso de LIKE. En realidad, no estaba al tanto del problema de la fuga. Lo que me preguntaba realmente en mi pregunta era si alguien alguna vez usaría LIKE en lugar de = para una coincidencia de cadena exacta. – kristof

0

LIKE es para coincidencia de comodines, donde as = (igual) es para una coincidencia exacta.

También creo que se utiliza para los campos que han sido catalogados por CATÁLOGOS DE TEXTO COMPLETO para las comparaciones de las líneas de núcleo duro.

1

Me encontré con el mismo problema. Se tardó aproximadamente un minuto y medio en ejecutar una consulta similar con =. Cuando cambié = a like, la consulta fue mucho más rápida.

  • Intente crear un índice para la columna que está comparando con. Esto aceleró la consulta significativamente.
  • Intenta ejecutar sp_updatestats. En mi caso esto hizo que la consulta se ejecutara en aproximadamente 6 segundos usando = sin el índice y casi al instante con el índice.
Cuestiones relacionadas