En el código de abajo yo soy insertar valores en una tabla y obtener el error «de Cadena o datos binarios podrían truncarse.»

Mi definición de la tabla:

CREATE TABLE urs_prem_feed_out_control
( 
bd_pr_cntl_rec_type  char(7)  NULL ,
pd_pr_cntl_acctg_dte char(6)  NULL ,
bd_pr_cntl_run_dte   char(10)  NULL ,
bd_pr_cntl_start_dte char(10)  NULL ,
bd_pr_cntl_end_dte   char(10)  NULL ,
bd_pr_cntl_rec_count char(16)  NULL ,
bd_pr_tot_premium    char(16)  NULL ,
bd_pr_tot_commission char(16)  NULL ,
fd_ctl_nbr           integer  NOT NULL 
)

DECLARE @cur_fd_ctl_nbr INT = 2, 
@acctg_cyc_ym_2 CHAR(6) = '201402',
@rundate CHAR (10) = CONVERT(CHAR(10),GETDATE(),101),
@cycle_start_dt DATETIME = '2014-02-17',
@cycle_end_dt DATETIME = '2014-02-24',
@record_count INT = 24704,
@tot_pr_premium DECIMAL(18,2) = 476922242,
@tot_pr_comm DECIMAL(18,2) = 2624209257

Insertar código (he declarado las variables como valores constantes para la prueba, que tomaron estos valores a partir de lo que fueron en tiempo de ejecución):

INSERT INTO urs_prem_feed_out_control
SELECT fd_ctl_nbr = @cur_fd_ctl_nbr,
       bd_pr_cntl_rec_type      = 'CONTROL',
       bd_pr_cntl_acctg_dte     = @acctg_cyc_ym_2,
       bd_pr_cntl_run_dte       = @rundate,
       bd_pr_cntl_start_dte     = CONVERT(CHAR(10),@cycle_start_dt,101),    
       bd_pr_cntl_end_dte       = CONVERT(CHAR(10),@cycle_end_dt,101),   
       bd_pr_cntl_rec_count     = RIGHT('0000000000000000' +     RTRIM(CONVERT(CHAR(16),@record_count)),16),                                         
       bd_pr_tot_premium        = CASE       
                                     WHEN @tot_pr_premium < 0
                                        THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_premium)*100))),18),1,15)
                                     ELSE
                                        '+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_premium)*100))),18),1,15)
                                     END,                                        
        bd_pr_tot_commission    = CASE       
                                     WHEN @tot_pr_comm < 0
                                        THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_comm)*100))),18),1,15)
                                     ELSE
                                        '+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_comm)*100))),18),1,15)
                                     END

Cuando miro a cada valor individual parece que todos ellos están dentro de la variable longitud de las restricciones de la tabla. Alguna idea de por qué estoy recibiendo este error?

Gracias!

  • Bueno, al menos una de ellos es demasiado largo – de lo contrario no obtendrá este error. Intentar sustituir una variable por vez, por ejemplo, con un NULL valor o un solo carácter (por ejemplo,*) – cuando el error desaparece, usted tiene su ofender valor de la columna!
  • Escribir un select con todas las len().
  • Reescribió la instrucción INSERT a una selección con todos los len()’s. Tengo 7,6,10,10,10,16,16,16 que corresponde exactamente a la longitud de las columnas. Cuando vuelvo a la INSERCIÓN puedo obtener la Cadena de datos binarios o sería truncado» error!!!
  • ¿Por qué estás estilo de mezcla 101 (mm/dd/yyyy) y el estilo de 120 (yyyy-mm-dd) en lugar de el uso de una manera absolutamente inequívoca formato como yyyymmdd? ¿Por qué usted convertir a varchar sin longitud? Y, ¿por qué no listado de los nombres de columna en la instrucción insert? Aviso de la columna que está último en la tabla, pero en primer lugar en su lista de selección. </facepalm>
  • Usted debe hacer todo este formato y relleno de los números en el lado del cliente, y aunque debería ser obvio ahora, ver aquí por qué su INSERT debe tener la (columna de la lista,que se define).
  • «Observe la columna que está último en la tabla, pero en primer lugar en su lista de selección» es el problema con esta consulta. Su sólo a la duración de esta consulta que no parece hacer straight-forward 🙂
  • Sí, lo sé, pero cuando veo a todas esas cosas malas que tengo que mencionar, también.

InformationsquelleAutor intA | 2014-06-23

3 Comentarios

  1. 4

    El problema con su consulta insert es EL ORDEN DE INSERCIÓN :

    SELECT fd_ctl_nbr = @cur_fd_ctl_nbr,

    Esta columna debe ser definida en el último lugar en la INSERT como la última columna definida en el script de la tabla.

    Cambiar tu consulta a este:

    Haciendo esto también funcionaría. Observe que la primera columna aquí en la SELECT dentro de la INSERT es sólo la forma en que usted ha proporcionado en su pregunta.

    Ver esto aquí-> http://sqlfiddle.com/#!3/0e09b/1

    Espero que esto ayude!!!

    • UGHHH. Por supuesto! Gracias!!
    • Ver la segunda parte de la respuesta, donde los nombres de columna se especifican. Hay un violín para que también (Véase el violín cerca de la final de la respuesta).
    • No había necesidad de editar la respuesta. Tanto las formas de HACER el trabajo. Es sólo una cuestión de «la mejor práctica» . Sin embargo, personalmente, creo prefieren & recomendar la especificación de los nombres de columna.
    • No es una cuestión de buenas prácticas, es una cuestión de la promoción de prácticas deficientes, especialmente desde la mala costumbre (que fue el causante de su problema) llegó primero. He considerado downvoting lugar, pero elegido para editar puesto que usted tiene la solución adecuada. Pero el OP necesario ver que la segunda solución es lo que se debe utilizar no el primero o esto va a romper la próxima vez que se pone columnas de orden.
    • La razón por la que ver la ‘solución’ es porque eso es lo que yo personalmente uso y estoy cómodo con. Realmente tuve que editar eso en mi estación de trabajo para llegar a el uno sin los nombres de columna. Pero sí, estoy de acuerdo, yo debería haber mencionado que en mi respuesta como este no es el ‘camino correcto’ de salir adelante. Y en otra nota, hay un montón de cosas que están mal con la forma en que la consulta se enmarca (Aaron Bertrand arroja algo de luz sobre esto en sus comentarios).
  2. 2

    Esta es la razón por la que nunca debe escribir una instrucción insert, sin especificar las columnas. Ya no lo wil tratar de poner los datos en las columnas en el orden que se encuentran en la tabla que no es en absoluto el orden que tienen en el.

    Otra cosa que puede suceder cuando usted este tipo de mensaje (pero creo que no se aplica en su caso, lo incluyo para las personas que buscan más adelante) es que el eeror en realidad proviene de un disparo y no el principal insertar.

    Finalmente, una nota sobre el diseño de base de datos, usted no debe usar char para las fechas, debe ser el uso de los campos de fecha. No se puede hacer de la fecha de matemáticas en un campo char y aceptará fecha incorrecta de valores como la feb30, 2014. Siempre es una mala idea para almacenar fechas como cualquier cosa excepto la fecha o valores datetime. En general char sólo debe ser utilizado en raras ocasiones, cuando una columna de tener siempre el mismo número de caracteres (como la de la 2 columna abreviatura del estado), no debe ser utilizado como el tipo de datos predeterminado. Usted necesita hacer un mejor trabajo de definición de tipos de datos que coincidan con el tipo y tamaño de datos que se almacenan. Puede ejecutar en problemas con consultas como ‘VA’ no es lo mismo que ‘VA ‘. En general, mi experiencia es que menos del 1 % de todos los campos de base de datos debe ser de tipo Char.

  3. 1

    Creo que puede ser beneficioso para corroborar su trabajo. Considere el siguiente ejemplo de código:

    Todos producen los siguientes: Cadena o datos binarios podrían truncarse.

Dejar respuesta

Please enter your comment!
Please enter your name here