¿Cómo puedo evitar que los enteros se conviertan silenciosamente en asteriscos en SQL Server?

8

Supongamos que tenemos una cuenta de tabla, hay un campo acct_type varchar(2)

Insert into account(acct_type) values(888)

Salida:

+-----------+
| acct_type |
+-----------+
| *         |
+-----------+

Espero que arroje un error cuando se inserte el desencadenador de instrucciones. ¿Por qué está almacenando *valor en la tabla?

Ankush
fuente
@SMor: o tal vez la tabla está definida incorrectamente. Si la aplicación quiere almacenar números (enteros) allí, tal vez la columna debe definirse como en integerlugar devarchar
a_horse_with_no_name

Respuestas:

11

Para el varchartipo de datos int, se lanzará un truncado en *lugar de arrojar un error (en este caso, ya que los tres dígitos no caben en a varchar(2)).

Esto no sucede con nvarchar

No hay forma de cambiar este comportamiento, se conserva por compatibilidad con versiones anteriores. Si este es un problema real para usted, puede agregar una restricción de verificación de que el valor en la columna no lo es, *pero no puedo imaginar ninguna situación en la que valga la pena hacerlo.

La solución es simplemente no hacer eso. Si debe insertar un y INTluego validarlo, -9 to 99primero está en el rango O utilice siempre comillas alrededor de valores destinados a una columna de cadena en lugar de depender de conversiones implícitas.

Martin Smith
fuente
Gracias Martin! .. ¿Cómo puedo poner una restricción de verificación para evitar el valor entero en varchar archivado ... ¿pueden ayudarme a escribir la sintaxis?
Ankush
ALTER TABLE account ADD CONSTRAINT CK_NoStar_acct_type CHECK (acct_type <> '*')pero casi seguro que no necesitas hacer esto. Hay un montón de char/varcharcolumnas en la naturaleza con una longitud de 10o menos donde esta es una posibilidad teórica que se lleva bien sin eso. La restricción de verificación, por supuesto, también bloqueará una inserción explícita de, *ya que no tiene forma de distinguir entre cómo *se llegó a
Martin Smith
1
Muchas gracias Martin !! ahora puedo explicarle adecuadamente a mi desarrollador con la sintaxis y los efectos secundarios de esto
Ankush
44
Creo que la verdadera pregunta es: si quieren almacenar valores enteros, ¿por qué es esto un varcharprincipio?
a_horse_with_no_name
@a_horse_with_no_name Si tiene una pregunta para el OP, colóquela en la pregunta, no en una respuesta. No serán notificados aquí. Diría que no hay nada en la pregunta que indique que solo tienen la intención de almacenar números enteros en esta columna, aunque "888" no es un valor válido para el de varchar(2)todos modos. Todo lo que se puede inferir es que lo intentaron al menos una vez y obtuvieron un resultado inesperado que preferirían haber cometido un error antes que fallar en silencio.
Martin Smith
-2

varchar acepta tipo de cadena. podrá insertar valor entre símbolos ''. parece Insert into account(acct_type) values('888') Pero mostrará un error porque la longitud máxima es 2. la longitud del varchar icrease o la longitud de su valor máximo debe ser 2Insert into account(acct_type) values('88')

Əşrəf Cəfərli
fuente
Su respuesta va en otra dirección que la pregunta, Sami indica que no se produce ningún error y se inserta un valor de '*'. El comentario que SMor ha dado es más probable en la dirección del problema.
Mark