Insertar en SQL Server: cómo identificar la columna que está causando el error de truncamiento


11

Tengo un procedimiento almacenado que inserta 650 campos en una tabla. La inserción está fallando con un error de truncamiento.

Es un simple

INSERT INTO
SELECT (a bunch of fields) 
FROM (a bunch of tables)

A continuación se muestra el mensaje de error:

Msg 8152, Nivel 16, Estado 14, Procedimiento DSP_Procedure, Línea 1075 Cadena o los datos binarios se truncarían.

¿Hay alguna forma rápida de identificar qué campo está causando el error de truncamiento?

El hecho de que la instrucción select que se inserte en la tabla tenga 650 campos hace que sea difícil determinar qué campo está causando el error de truncamiento.

Estoy pensando que tal vez pueda comentar bloques de campos a la vez para que el SP solo inserte 100 campos a la vez y luego ejecute el SP 6 o 7 veces diferentes hasta que al menos pueda reducir a un grupo de 100 campos eso contendrá el campo que está causando el error de truncamiento.

Alternativamente, estoy pensando que tal vez pueda simplemente SELECT INTOuna nueva tabla y luego comparar las longitudes de datos en la tabla con las longitudes de datos de la tabla de destino en la que estoy tratando de insertar en mi SP para ver qué campo contiene una longitud de campo más larga de lo esperado. ..

Estoy usando SQL Server 2014.

¿Alguna alternativa más fácil?


1
Iría a INFORMATION_SCHEMA.COLUMNS y compararía los tipos de datos con los que está intentando insertar. Lamentablemente, el servidor SQL no tiene tipos de datos dinámicos para la declaración de variables como ORACLE.
MguerraTorres

2
Usaría su segunda opción, insertar en una nueva tabla (o #temp) y luego comparar las longitudes de columna. O podría ajustar LEN () alrededor de todas las columnas en la selección y luego hacer que una consulta externa haga un MAX () para cada ... que le daría la mayor longitud de texto para los campos. Por supuesto, eso supone que es un campo de char que le está dando problemas. ¿No usa smalldatetime o tinyint?
Jonathan Fite

1
Me gustaría ir con el enfoque "Seleccionar en" y comparar longitudes de columna, sí. Tal vez con "WHERE 1 = 0" para que la tabla no tenga filas. Incómodo si su SELECT no incluye nombres únicos para las columnas seleccionadas. Formateo listas de columnas largas como una línea de script por columna, luego el nombre de columna "AS" en la siguiente línea si es necesario, y una línea en blanco después de cuatro columnas para que sea más fácil mantener el lugar en la lista. Eso también admite la selección de muchas líneas y hacer Ctrl + K Ctrl + C para cambiarlas a comentarios, para que pueda atacar la operación Insertar de esa manera, pero las columnas que quedaron fuera deberían ser anulables.
Robert Carnegie

Respuestas:



9

Desafortunadamente, ha encontrado una "característica" bastante antigua . Ha habido un boleto de Connect abierto desde 2008, y durante casi diez años esto no ha sido lo suficientemente significativo como para justificar una solución.

La solución estándar es, como se imaginó, select into...seguida de una comparación de metadatos de tabla. Otra posibilidad es la búsqueda binaria en la columna ofensiva, pero también es trabajo manual. Hay algunos trucos para la comparación de metadatos, pero no existe una solución simple y elegante. Quizás algunas herramientas de terceros serían de ayuda, pero no estoy al tanto de eso.


1

Usar (QUERYTRACEON 460) no funcionó para mí al ponerlo al final de mi consulta.

Lo encendí en el nivel DB y funcionó:

DBCC TRACEON(460, -1);
GO

Pero asegúrese de volver a apagarlo una vez que haya encontrado y solucionado el problema, ¡no lo deje encendido!

DBCC TRACEOFF(460, -1);
GO
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.