2010-03-11 34 views
7

Cuando obtiene este error, lo primero que pregunta es, ¿qué columna? Lamentablemente, SQL Server es sin ayuda aquí. Entonces comienzas haciendo prueba y error. Bueno, ahora tengo una declaración como:Cadena o datos binarios se truncarán - Problema de Heisenberg

INSERT tbl (A, B, C, D, E, F, G) 
SELECT A, B * 2, C, D, E, q.F, G 
    FROM tbl 
     ,othertable q 
WHERE etc etc 

Tenga en cuenta que

  • Algunos valores se modifican o vinculados desde otra mesa, pero la mayoría de los valores están llegando de la tabla original, por lo que realmente no puede causar truncamiento volviendo al mismo campo (que yo sepa).
  • campos eliminación de uno a la vez con el tiempo hace que el error desaparece, si lo hago de forma acumulativa, pero — y aquí viene lo bueno — no importa qué campos elimino. Es como si SQL Server se estuviera oponiendo a la longitud total de la fila, lo que dudo, ya que solo hay unos 40 campos en total, y nada grande.

¿Alguien ha visto esto antes?

Gracias.

ACTUALIZACIÓN: También hice pruebas "horizontales", filtrando el SELECT, con el mismo resultado. En otras palabras, si yo digo

  • donde id entre 1 y 100: Error
  • donde id entre 1 y 50: No hay error
  • donde id entre 50 y 100: No hay error

Probé muchas combinaciones, y no puede limitarse a una sola fila.

+0

Como auxiliar de depuración: podría intentar escribir un cursor que pase por la tabla fuente e insertar las filas una a una. Tal vez el error se encuentra en una de las filas? – Tomalak

+0

¿Cuáles son las restricciones de clave foriegn? ¿Hay alguno? –

+0

@Vecdid: no, no hay restricciones de ningún tipo, ni siquiera una clave principal. Es solo una copia desechable de una tabla remota, utilizada solo durante esta rutina, creada por SELECT * INTO. – harpo

Respuesta

5

Aunque la tabla no tenía claves, restricciones, índices o disparadores, hizo tiene estadísticas, y ahí está el problema. Maté a todas las estadísticas de la tabla utilizando este script

http://sqlqueryarchive.blogspot.com/2007/04/drop-all-statistics-2005.html

Y voilá , el inserto fue de nuevo a funcionar muy bien. ¿Por qué las estadísticas causan este error? No lo sé, pero ese es otro problema ...

ACTUALIZACIÓN: Este error volvió incluso con las estadísticas eliminadas. Porque estaba convencido de que el mensaje en sí era inexacta (no hay pruebas de truncamiento), fui con this solution lugar:

SET ANSI_WARNINGS OFF 
INSERT ... 
SET ANSI_WARNINGS ON 

Está bien, es más de un truco que una solución, pero me permite — y es de esperar alguien más — para pasar a otras cosas.

+0

Debido a que la longitud del atributo total de las estadísticas fue probablemente mayor que [900 bytes] [1]? Sin embargo, no estoy seguro de si esto se aplica a las estadísticas y no estoy convencido. ¿Tiene una referencia, por favor, porque me gustaría saber por qué las estadísticas se truncan cuando son simplemente histogramas binarios (IIRC) – gbn

0

Si se ve como "longitud total", ¿tiene un desencadenante de auditoría concatenando las columnas para el registro?

Editar: después de su actualización, realmente consideraría el hecho de que tiene un disparador que causa esta ...

Editar 2, después de ver su respuesta estadísticas ...

Debido a que las estadísticas totales atributo de longitud fue probablemente mayor que 900 bytes? Sin embargo, no estoy seguro de si esto se aplica a las estadísticas y no estoy convencido.

¿Tiene una referencia por favor, porque me gustaría saber por qué estadísticas se truncan cuando son histogramas simplemente binarios (IIRC)

+0

Estoy comprobando con el dba, pero no lo creo. ¿Esto significa que en realidad es el * log * donde se origina la advertencia de truncamiento? – harpo

+0

tabla de registro, no registro de transacciones. Por ejemplo, "OrderHistory" coincide con la tabla "Order" – gbn

0

Sí, cuando me encontré con esto, tuve que crear otra tabla/tablas que imitan la estructura actual. Luego no cambié el código, pero cambié el tamaño de los tipos de datos a todos los nvarchar (MAX) para cada campo hasta que se detuvo, luego los eliminé uno por uno. Sí, largo y arrastrado, pero tuve problemas importantes para intentar cualquier otra cosa. Una vez que probé un montón de cosas que me estaban causando demasiado dolor de cabeza, decidí adoptar el enfoque de "hombre de las cavernas", ya que nos reímos más tarde.

También he visto un problema similar con FKs, en el que debe preguntar:

¿Cuáles son las restricciones de clave externa? ¿Hay alguno?

Puesto que no hay ninguna, tratar componente DataMgr de este tipo:

http://www.bryantwebconsulting.com/blog/index.cfm/2005/11/21/truncated

también mira esto:

http://forums.databasejournal.com/showthread.php?t=41969

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=138456

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=97349

También podría volcar la tabla que está seleccionando en una tabla temporal y averiguar qué línea da el error si se equivoca en una tabla temporal.

Debe indicar la línea en el error, si coloca cada columna en otra línea, debe indicar exactamente dónde está bombardeando.

0

Hay un límite máximo de tamaño de fila en SQL Server 2005. Consulte here.

La mayoría de las veces se encontrará con esta w/muchas columnas nvarchar.

1

¿Existe una razón por la que no se puede simplemente emitir los campos como el equivalente estructural de la columna de destino, así:

Select Cast(A as varchar(42)) 
, Cast(B * 2 as Decimal(18,4)) 
, Cast(C As varchar(10)) 
... 
From Table 

La desventaja de este enfoque es que truncará los valores de texto en su carácter límite. Sin embargo, si está "seguro" de que esto no debería suceder, entonces no habrá daños.

+0

. He examinado los datos manualmente, y no hay un solo valor que deba causar el error. Comprobé el MAX (LEN()) de cada columna varchar con el tamaño del campo de recepción, así como todos los valores numéricos. Claramente, algo más está funcionando aquí, simplemente no sé qué. – harpo

+0

Luego intente enviar todas las columnas a las especificaciones de tipo de datos de la tabla de destino y vea si la consulta se procesará. – Thomas

+0

O establezca ANSI_WARNINGS OFF haciendo el INSERTO y luego comparando con el operador EXCEPT el SELECT original para ver qué no se insertó como se esperaba. –

1

En algunos casos, puede tener un problema si tiene alguna otra columna con valores predeterminados que puedan causar el problema.

Ej. es posible que haya agregado una columna para rastrear al usuario que creó la fila, como USER_ENTERED con el valor predeterminado de suser_sname() pero la longitud de la columna es menor que el nombre de usuario actual.

Cuestiones relacionadas