2011-06-28 14 views
5

Estoy solucionando un problema del mensaje de error del servidor SQL 8152 "Cadena o datos binarios se truncarán" en algunos escenarios solamente. La siguiente consulta es similar a la que arroja el error.¿Por qué obtengo "Cadena o datos binarios se truncarán" solo en algunos casos?

CREATE TABLE SourceValues (
    SourceId INT IDENTITY (1,1), 
    SourceValue VARCHAR(3) 
) 
GO 
INSERT INTO SourceValues (SourceValue) VALUES ('aaa') 
INSERT INTO SourceValues (SourceValue) VALUES ('aab') 
INSERT INTO SourceValues (SourceValue) VALUES ('aa') 
INSERT INTO SourceValues (SourceValue) VALUES ('ab') 
INSERT INTO SourceValues (SourceValue) VALUES ('a') 
INSERT INTO SourceValues (SourceValue) VALUES ('b') 
GO 

PRINT 'NOT WORKING #1' 
CREATE TABLE TargetValues (TargetValue VARCHAR(2)) 
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue 
FROM SourceValues s1, SourceValues s2 
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab' 
DROP TABLE TargetValues 
GO 

PRINT 'NOT WORKING #2' 
CREATE TABLE TargetValues (TargetValue VARCHAR(2)) 
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue 
FROM SourceValues s1, SourceValues s2 
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab' 
ORDER BY s1.SourceValue 
DROP TABLE TargetValues 
GO 

PRINT 'WORKING #1' 
CREATE TABLE TargetValues (TargetValue VARCHAR(2)) 
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue 
FROM SourceValues s1, SourceValues s2 
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab' 
ORDER BY s2.SourceValue -- <-- using s2 instead of s1 for order 
DROP TABLE TargetValues 
GO 

PRINT 'WORKING #2' 
CREATE TABLE TargetValues (TargetId INT IDENTITY (1,1),TargetValue VARCHAR(2)) -- <-- using identity column 
INSERT INTO TargetValues (TargetValue) 
SELECT s1.SourceValue 
FROM SourceValues s1, SourceValues s2 
WHERE s1.SourceId=s2.SourceId+1 AND s1.SourceValue!='aab' 
DROP TABLE TargetValues 
GO 

DROP TABLE SourceValues 

El problema ocurrió en la consulta 'NO FUNCIONANDO 1', los otros son algunas reflexiones sobre soluciones. ¿Alguien sabe acerca de las diferencias entre las consultas que no funcionan y las consultas que trabajan?

Probé esto en SQL Server 2005, SQL Server 2008 y SQL Server 2008 R2 y obtuve los mismos resultados. Pero escuché que todas las consultas fallaron en otra instancia de SQL Server 2008 R2.

Tenga en cuenta que ya he resuelto este problema al establecer varchar en la tabla TargetValues ​​al tamaño de 3 (corrigió el error).

Respuesta

1

Si estoy en lo cierto, intente agregar 'aaa' a un campo varchar (2). Eso no es posible porque los datos se truncarán.

+0

No, aaa no está insertado. Se elimina por join. – dwonisch

3

Es entonces cuando los datos se desbordará la longitud del ejemplo campo abc en char(2)

Tienes aaa en los datos de origen

No se puede apagar o truncan

Ver SQL Server silently truncates varchar's in stored procedures para más de lo que probablemente nunca quisiste saber

Edit:

Este es un comportamiento extraño

Esto todavía falla con un explícito JOIN y rompe uno de los "trabajadores" consultas

SELECT s1.SourceValue DE SourceValues ​​s1 s2 UNEN SourceValues ​​En s1.SourceId = + s2.SourceId 1 DONDE s1.SourceValue <> 'AAB' ordenado por s2.SourceValue, s1.SourceValue

no puedo encontrar nada en MS Conectar sobre este servidor SQL

+0

Creo que si DESACTIVA ANSI_WARNINGS, permitirá silenciosamente insertar y truncar el valor – AdaTheDev

+0

@AdaTheDev: true, pero se rompen las vistas indexadas, los servidores enlazados, etc. No es una opción compatible a largo plazo – gbn

+0

Sí, de acuerdo. Solo para aclarar, no recomiendo que esté apagado :) – AdaTheDev

0

conoce los esquemas son diff erent. todavía está seleccionando una columna VARCHAR (3) en última instancia en una columna de recepción VARCHAR (2), a pesar de la cláusula where. CAST/CONVERT la selección resultante en varchar (2) y funcionará. Sin embargo, probablemente no sea una buena práctica tener el tipo resultante vinculado así a la cláusula where - la cláusula where podría devolver una columna de 3 letras en una fecha posterior (depende de tus datos, por supuesto) y la rompería, pero un CAST explícito/CONVERTIR en la selección resolvería este problema específico.

Cuestiones relacionadas