¿Cómo conservo los ceros a la izquierda cuando inserto un número en esta tabla? [cerrado]

10

He insertado dos registros en una tabla.

create table num(id int)
insert into num values(0023)
insert into num values(23)
select * from num

Cuando los consulto, todos se muestran como 23. Significa que SQL Server ignora los ceros iniciales. ¿Cuál es el mecanismo detrás de eso? ¿Cómo puedo hacer que SQL Server devuelva los valores cuando los inserté (es decir, 0023y 23)?

user8365
fuente
2
¿Por qué te importan los ceros a la izquierda? Si son significativos para su sistema, iddeberían ser de tipo VARCHARo similar.
Nick Chammas
Exactamente, ¿cómo espera que se codifique 0023 en la base de datos como algo diferente de 23 o 023 o 0000000023? Todos representan el mismo NÚMERO. E int es un tipo de datos NUMBER. No hay lugar para que el servidor almacene este valor de "número inicial de ceros decimales".
ErikE
Esta es una pregunta pobre, y habría sido cubierta en cualquier introducción a la clase de programación. Un int nunca puede almacenar ceros a la izquierda, debido a la naturaleza de los ints. Esto se puede resolver observando cualquier cantidad de recursos web. Esto no necesita la entrada de un administrador de base de datos.
jcolebrand
1
Los ceros iniciales están implícitos. Además de usar una cadena en su lugar, si necesita un número específico de ceros a la izquierda, es información adicional más allá de lo que se almacena en una columna int. Una opción es usar una columna de cadena, pero otra opción es almacenar el número de ceros a la izquierda en otra columna o en la interfaz de usuario. si la IU siempre se formatea a 4 dígitos con ceros iniciales, por ejemplo, entonces ha almacenado esta información en la IU. Si necesita que el número de ceros varíe y se conserve para cada registro, puede almacenar esa información en un campo separado.
Dave Cousineau el

Respuestas:

27

0023No es un número. Es una cuerda. 23es el numero SQL Server puede reconocer que esos ceros adicionales no son necesarios para definir el número, por lo que los ignora. Si desea mostrar un valor como 0023 para la aplicación, le sugiero que realice el formateo en el lado de la aplicación. De esa forma, el número almacenado en SQL Server sigue siendo un número si desea realizar sumas, agregaciones u otros cálculos. Si realmente tiene que almacenarlo como ' 0023', debe convertirlo en un campo de caracteres; char, varchar, nvarchar, nchar.

Grant Fritchey
fuente
Si el 0023 es una cadena, ¿cómo puedo insertar el valor en la tabla en la que he definido el id como formato int?
user8365
@ user8365 - Defina idcomo VARCHARo simplemente inserte 23 en lugar de 0023
Lamak
55
@ user8365: pregunta si puede hacer que SQL Server viole la integridad del dominio de ese campo. No puedes Si 0023es una cadena, almacénela como una cadena. Si no es así, guárdelo como un INT y olvídese de los ceros iniciales.
Nick Chammas
Exactamente lo que dijo @NickChammas. No tienes otra opción aquí. 23 es un número, 0023 es una cadena. Si quieres un número, trátalo como un número. Como dice mi respuesta, si necesita ordenar como un número, sumar, restar, multiplicar, dividir, etc., como un número, entonces debe ser un número. No hay opciones Sin argumentos. Los ceros a la izquierda solo están formateando. Haz eso en el código de la aplicación o en algún lugar.
Grant Fritchey
@Grant No puedo aceptar que los ceros iniciales solo estén formateando. Son legítimos en cualquier sistema de numeración; sin embargo, 0023b10 = 23b10; entonces, cualquier sistema de almacenamiento gana cierto grado de compresión al no codificar todos los ceros iniciales. Entonces, fundamentalmente nuestro interrogador está haciendo la pregunta equivocada. ¿Por qué 0023 no es un número entero? Es un entero! Simplemente no necesitamos codificar una infinidad de números iniciales para representarlo como tal.
Ooutwire
5

Ya se dijo en otras respuestas que 00023es un número; Solo quiero agregar que puede usar columnas calculadas para mostrar ese número usando un formato personalizado. Por ejemplo,

create table num_table(id int not null primary key identity(1,1),
num int, leading_zeros smallint,
constraint chk_leading_zero_nonnegative check (leading_zero>=0),
num_formatted as replicate('0',coalesce(leading_zeros,0)) +cast(num as varchar(10)));
insert into num_table(num,leading_zeros) values(23,2) ;
select num_formatted from num_table; -- output '0023'
a1ex07
fuente
Buen punto, absolutamente digno de mención.
Grant Fritchey
0

0023 es un número, pero los tipos de datos int y otros tipos de números no almacenan ceros a la izquierda ya que no hay una razón matemática para hacerlo.

Si necesita almacenar ceros a la izquierda, use un tipo de datos de cadena como, char, varchar, etc.

Jimbo
fuente
1
Si suponemos que INTes de longitud fija (como 32 bits) y se usa notación binaria para almacenarlos, los ceros iniciales se almacenan. Pero no se muestran en la salida.
ypercubeᵀᴹ
@ypercube - Correcto, pero la cantidad de ceros iniciales es simplemente lo que se requiere para llenar los 32 bits (en lugar de ser definible por el usuario).
Nick Chammas
@ Nick: Sí, no discutas allí. Creo que el punto NO es si se almacenan o no ceros iniciales. Es si dos versiones del mismo número pueden almacenarse en el tipo de datos, una con y otra sin ceros a la izquierda.
ypercubeᵀᴹ
Pero esto no tiene sentido. Dos ceros iniciales decimales no tienen absolutamente ninguna relación con el número de ceros iniciales en un entero de 32 bits. Considere el número decimal 15--esto sólo toma un dígito hexadecimal, F. Ya tienen un número diferente de "ceros iniciales". 2147483647 son 10 dígitos, pero en hexadecimal son solo 7FFFFFFF u 8 dígitos.
ErikE
Fundamentalmente, uno debe considerar el sistema de numeración matemática que estamos usando ... en este caso decimal (base 10). 23 es un número decimal; es 0x1000 + 0x100 + 2x10 + 3 = 23. En octal, es 2X8 + 3 y así sucesivamente. Entonces, para decirle al motor de almacenamiento, "almacenar 23 con dos ceros iniciales" no es útil, ya que simplemente codifica el mismo resultado final, es decir, 23. SQL Server no ignora sus ceros, simplemente le devuelve un valor decimal igual al número que insertó, es decir, 0023 o 23.
ooutwire