Como preservo os zeros à esquerda quando insiro um número nesta tabela? [fechadas]

10

Eu inseri dois registros em uma tabela.

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

Quando os consulto, todos são exibidos como 23. Isso significa que o SQL Server ignora os 0s principais. Qual é o mecanismo por trás disso? Como posso fazer com que o SQL Server retorne os valores quando os inseri (ie 0023e 23)?

user8365
fonte
2
Por que você se importa com os zeros à esquerda? Se eles são significativos para o seu sistema, iddeve ser do tipo VARCHARou similar.
precisa
Exatamente como você espera que o 0023 seja codificado no banco de dados como algo diferente de 23 ou 023 ou 0000000023? Todos eles representam o mesmo número. E int é um tipo de dados NUMBER. Não há lugar para o servidor armazenar esse valor "número inicial de zeros decimais".
ErikE
Essa é uma pergunta ruim e teria sido abordada em qualquer introdução à aula de programação. Um int nunca pode armazenar zeros à esquerda, devido à natureza dos ints. Isso pode ser resolvido observando qualquer número de recursos da web. Isso não precisa da entrada de um administrador de banco de dados.
Jcolebrand
11
Os zeros à esquerda estão implícitos. Além de usar uma string, se você precisar de um número específico de zeros à esquerda, isso é uma informação extra além do que é armazenado em uma coluna int. Uma opção está usando uma coluna de cadeia, mas outra opção é armazenar o número de zeros à esquerda em outra coluna ou na interface do usuário. se a interface do usuário sempre formata para 4 dígitos com zeros à esquerda de preenchimento, por exemplo, você armazenou essas informações na interface do usuário. Se você precisar que o número de zeros varie e seja preservado para cada registro, poderá armazenar essas informações em um campo separado.
Dave Cousineau

Respostas:

27

0023não é um número. É uma corda. 23é o número O SQL Server reconhece que esses zeros extras não são necessários para definir o número e, portanto, os ignora. Se você deseja exibir um valor como 0023 para o aplicativo, sugiro fazer a formatação no lado do aplicativo. Dessa forma, o número armazenado no SQL Server ainda é um número se você desejar fazer adição, agregação ou outros cálculos. Se você realmente precisar armazená-lo como ' 0023', precisará convertê-lo em um campo de caractere; char, varchar, nvarchar, nchar.

Grant Fritchey
fonte
Se o 0023 for string, como posso inserir o valor na tabela que defini o id como formato int?
user8365
@ user8365 - Ou defina idcomo VARCHARou apenas inserir 23 em vez de 0023
Lamak
5
@ user8365 - Você está perguntando se pode fazer o SQL Server violar a integridade do domínio desse campo. Você não pode. Se 0023for uma sequência, armazene-a como uma sequência. Caso contrário, armazene-o como um INT e esqueça os zeros à esquerda.
precisa
Exatamente o que o @NickChammas disse. Você não tem escolha aqui. 23 é um número, 0023 é uma sequência. Se você deseja um número, trate-o como um número. Como minha resposta diz, se precisar classificar como um número, adicionar, subtrair, multiplicar, dividir etc., como um número, será necessário que seja um número. Sem escolhas. Sem argumentos. Os zeros à esquerda são apenas formatação. Faça isso no código do aplicativo ou em algum lugar.
Grant Fritchey
@ Granant Não posso concordar que os zeros à esquerda estão apenas formatando. Eles são legítimos em qualquer sistema numérico; no entanto, 0023b10 = 23b10; portanto, qualquer sistema de armazenamento ganha algum grau de compactação ao não codificar todos os zeros iniciais. Então, fundamentalmente, nosso questionador está fazendo a pergunta errada. Por que 0023 não é um número inteiro? É um número inteiro! Nós simplesmente não precisamos codificar uma infinidade de numerais iniciais para representá-lo como tal.
ooutwire
5

Já foi dito em outras respostas que 00023é um número; Eu só quero acrescentar que você pode usar colunas computadas para mostrar esse número usando o formato personalizado. Por exemplo,

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
fonte
Bom ponto, absolutamente digno de nota.
Grant Fritchey
0

0023 é um número, mas os tipos de dados int e outros números não armazenam zeros à esquerda, pois não há motivo matemático para fazê-lo.

Se você precisar armazenar os zeros à esquerda, use um tipo de dados como string, char, varchar etc.

Jimbo
fonte
11
Se assumirmos que INTé de comprimento fixo (como 32 bits) e a notação binária é usada para armazená-los, os zeros à esquerda são realmente armazenados. Mas eles não são exibidos na saída.
ypercubeᵀᴹ
@ypercube - Certo, mas o número de zeros à esquerda é simplesmente o que é necessário para preencher os 32 bits (em oposição aos definidos pelo usuário).
21412 Nick Chammas
@ Nick: Sim, não discuta lá. Acho que o ponto NÃO é se os zeros à esquerda são armazenados ou não. É se duas versões do mesmo número podem ser armazenadas no tipo de dados, uma com e outra sem zeros à esquerda.
ypercubeᵀᴹ
Mas isso não faz sentido. Dois zeros iniciais decimais não têm absolutamente nenhuma relação com o número de zeros iniciais em um número inteiro de 32 bits. Considere o número decimal 15- isto leva apenas um dígito em hexadecimal F,. Eles já têm um número diferente de "zeros à esquerda". 2147483647 tem 10 dígitos, mas em hexadecimal são apenas 7FFFFFFF ou 8 dígitos.
ErikE 16/03
Fundamentalmente, deve-se considerar o sistema numérico matemático que estamos usando ... neste caso decimal (base 10). 23 é um número decimal; é 0x1000 + 0x100 + 2x10 + 3 = 23. No octal, é 2X8 + 3 e assim por diante. Portanto, para dizer ao mecanismo de armazenamento, "armazenar 23 com dois zeros à esquerda" não é útil, pois apenas codifica o mesmo resultado final, ou seja, 23. O SQL Server não ignora seus zeros, apenas retorna um valor decimal para você igual ao número que você inseriu, ou seja, 0023 ou 23.
ooutwire