2010-11-12 13 views
40

En SQL Server 2008 tengo una tabla llamada Zone con una columna ZoneReference varchar(50) not null como clave principal.Cláusula WHERE de SQL que coincide con los valores de los espacios finales

Si funciono con la siguiente consulta:

select '"' + ZoneReference + '"' as QuotedZoneReference 
from Zone 
where ZoneReference = 'WF11XU' 

me sale el siguiente resultado:

"WF11XU " 

Nota el espacio final.

¿Cómo es esto posible? Si el espacio final realmente está allí en esa fila, entonces esperaría devolver cero resultados, así que supongo que es algo más que SQL Server Management Studio muestra de forma extraña.

En el código C# llamando al zoneReference.Trim() lo quita, sugiriendo que es algún tipo de carácter de espacio en blanco.

¿Alguien puede ayudar?

Respuesta

60

Ese es el resultado esperado: en SQL Server, el operador = ignora los espacios finales al hacer la comparación.

SQL Server sigue la especificación ANSI/ISO SQL-92 (Sección 8.2,, Reglas generales n. ° 3) sobre cómo comparar cadenas con espacios. El estándar ANSI requiere relleno para las cadenas de caracteres utilizadas en las comparaciones de modo que sus longitudes coincidan antes de compararlas. El relleno afecta directamente a la semántica de WHERE y HAVING predicados de cláusula y otras comparaciones de cadenas de Transact-SQL. Por ejemplo, Transact-SQL considera que las cadenas 'abc' y 'abc' son equivalentes para la mayoría de las operaciones de comparación.

La única excepción a esta regla es el predicado LIKE. Cuando el lado derecho de una expresión de predicado LIKE presenta un valor con un espacio final, SQL Server no rellena los dos valores con la misma longitud antes de que se produzca la comparación. Como el propósito del predicado LIKE, por definición, es facilitar las búsquedas de patrones en lugar de simples pruebas de igualdad de cadenas, esto no infringe la sección de la especificación ANSI SQL-92 mencionada anteriormente.

Source

+0

Creo 'WHERE ZoneReference = 'WF11XU' Y DATALENGTH (ZoneReference) = DATALENGTH ('WF11XU')' también funcionará y podría ser más rápido que 'LIKE' – a1ex07

+0

@MarkByers Sí veo - Intenté' donde 'WF11XU' como ZoneReference' ¡y funcionó! Más raro y más extraño. Aún así, ¡todos los días son día de escuela! –

-3

tratar

select Replace('"' + ZoneReference + '"'," ", "") as QuotedZoneReference from Zone where ZoneReference = 'WF11XU' 
+0

Te has perdido el punto un poco. El punto era que no esperaba que la cláusula 'where' coincidiera con este registro. –

+0

Sí, creo que Neil sabía cómo hacerlo, solo se preguntaba por qué estaba viendo el comportamiento observado. –

+1

Los votos hacia abajo son un poco duros ¿no? – AGoodDisplayName

2

Sí, Mark es correcta. Ejecute el siguiente SQL:

create table #temp (name varchar(15)) 
insert into #temp values ('james ') 
select '"' + name + '"' from #temp where name ='james' 
select '"' + name + '"' from #temp where name like 'james' 
drop table #temp 

embargo, la afirmación sobre el 'como' declaración parece no trabajar en el ejemplo anterior. Salida:

(1 row(s) affected) 

----------------- 
"james " 

(1 row(s) affected) 


----------------- 
"james " 

(1 row(s) affected) 

EDIT: Para conseguir que funcione, usted podría poner al final:

and name <> rtrim(ltrim(name)) 

feo sin embargo.

Edit2: Teniendo en cuenta los comentarios abovem, la siguiente funcionaría:

select '"' + name + '"' from #temp where 'james' like name 
5

espacios finales no siempre son ignorados. Experimenté este problema hoy. Mi mesa tenía columnas NCHAR y se estaba uniendo a los datos de VARCHAR. Como los datos en la tabla no eran tan amplios como su campo, SQL Server agregó automáticamente espacios finales.

Tenía una ITVF (función en línea con valores de tabla) que tomaba varios parámetros. Los parámetros se usaron en un JOIN a la tabla con los campos NCHAR.

Las uniones fallaron porque los datos pasados ​​a la función no tenían espacios finales pero sí los datos en la tabla. ¿Por qué fue eso?

Me estaba tropezando con DATA TYPE PRECEDENCE. (Ver http://technet.microsoft.com/en-us/library/ms190309.aspx)

Al comparar cadenas de diferentes tipos, el tipo de precedencia inferior se convierte en el mayor Tipo de precedencia antes de la comparación. Entonces mis parámetros VARCHAR se convirtieron a NCHAR. Los NCHARs fueron comparados, y aparentemente los espacios fueron significativos.

¿Cómo solucioné esto? Cambié la definición de la función para usar los parámetros de NVARCHAR, que son de una precedencia más alta que NCHAR. Ahora los NCHAR se cambiaron automáticamente por SQL Server en NVARCHAR y los espacios finales se ignoraron.

¿Por qué no acabo de realizar un RTRIM? Las pruebas revelaron que RTRIM eliminó el rendimiento, impidiendo las optimizaciones de JOIN que de otra forma hubiera utilizado SQL Server.

¿Por qué no cambiar el tipo de datos de la tabla? Las tablas ya están instaladas en los sitios de los clientes, y no quieren ejecutar scripts de mantenimiento (tiempo + dinero para pagar DBA) ni darnos acceso a sus máquinas (comprensible).

Cuestiones relacionadas