Jak zachować początkowe zera po wstawieniu liczby do tej tabeli? [Zamknięte]

10

Wstawiłem dwa rekordy do tabeli.

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

Kiedy je pytam, wszystkie wyświetlają się jako 23. Oznacza to, że SQL Server ignoruje wiodące 0. Jaki jest za tym mechanizm? W jaki sposób SQL Server może zwracać wartości po ich wstawieniu (tj. 0023I 23)?

użytkownik8365
źródło
2
Dlaczego przejmujesz się zerami wiodącymi? Jeśli mają znaczenie dla twojego systemu, idpowinny być typu VARCHARlub podobne.
Nick Chammas,
Dokładnie w jaki sposób kod 0023 zostanie zakodowany w bazie danych jako coś innego niż 23 lub 023 lub 0000000023? Wszystkie reprezentują ten sam NUMER. I int jest typem danych NUMBER. Serwer nie ma miejsca na przechowywanie tej wartości „wiodącej liczby zer dziesiętnych”.
ErikE
To kiepskie pytanie, które zostałoby ujęte w każdym wprowadzeniu do klasy programowania. Int nigdy nie może przechowywać zer wiodących ze względu na naturę ints. Można to rozwiązać, sprawdzając dowolną liczbę zasobów internetowych. Nie wymaga to danych administratora bazy danych.
jcolebrand
1
Implikowane są zera wiodące. Oprócz użycia ciągu zamiast tego, jeśli potrzebujesz określonej liczby zer wiodących, to dodatkowe informacje poza tym, co jest przechowywane w kolumnie int. Jedna opcja korzysta z kolumny ciągów, ale inna opcja przechowuje liczbę zer wiodących w innej kolumnie lub w interfejsie użytkownika. jeśli na przykład interfejs użytkownika zawsze formatuje do 4 cyfr z dopełniającymi zerami wiodącymi, to informacje te zostały zapisane w interfejsie użytkownika. Jeśli potrzebujesz # zer, aby się różnić i zachować dla każdego rekordu, możesz zapisać te informacje w osobnym polu.
Dave Cousineau

Odpowiedzi:

27

0023nie jest liczbą. To jest struna. 23jest liczbą. SQL Server jest w stanie rozpoznać, że te dodatkowe zera nie są potrzebne do zdefiniowania liczby, więc je ignoruje. Jeśli chcesz, aby aplikacja miała wartość 0023, sugeruję wykonanie formatowania po stronie aplikacji. W ten sposób liczba przechowywana w SQL Server nadal jest liczbą, jeśli chcesz dodawać, agregować lub wykonywać inne obliczenia. Jeśli naprawdę musisz go zapisać jako „ 0023”, musisz przekonwertować go na pole postaci; char, varchar, nvarchar, nchar.

Grant Fritchey
źródło
Jeśli ciąg 0023 jest ciągiem, jak mogę wstawić wartość do tabeli, w której zdefiniowałem identyfikator jako format int?
user8365,
@ user8365 - Zdefiniuj idjako VARCHARlub po prostu wstaw 23 zamiast 0023
Lamak
5
@ user8365 - Pytasz, czy możesz zmusić SQL Server do naruszenia integralności domeny tego pola. Nie możesz Jeśli 0023jest ciągiem, zapisz go jako ciąg. Jeśli nie, zapisz go jako INT i zapomnij o zerach wiodących.
Nick Chammas,
Dokładnie to, co powiedział @NickChammas. Nie masz tutaj wyboru. 23 to liczba, 0023 to ciąg znaków. Jeśli chcesz numer, potraktuj go jak liczbę. Tak jak moja odpowiedź mówi, jeśli trzeba sortować jak liczbę, dodawać, odejmować, mnożyć, dzielić, itd., Jak liczbę, to musi to być liczba. Brak wyborów Bez argumentów. Zera wiodące to tylko formatowanie. Zrób to w kodzie aplikacji lub gdzieś.
Grant Fritchey,
@Grant Nie mogę się zgodzić, że początkowe zera to tylko formatowanie. Są one zgodne z prawem w dowolnym systemie liczbowym; jednakże 0023b10 = 23b10; więc każdy system pamięci masowej zyskuje pewien stopień kompresji, nie kodując wszystkich zer wiodących. Zasadniczo nasz pytający zadaje złe pytanie. Dlaczego 0023 nie jest liczbą całkowitą? To jest liczba całkowita! Po prostu nie musimy kodować nieskończoności wiodących cyfr, aby przedstawić je jako takie.
ooutwire
5

Było już powiedziane w innych odpowiedziach, które 00023są liczbą; Chcę tylko dodać, że można użyć kolumn obliczeniowych do wyświetlenia tej liczby w niestandardowym formacie. Na przykład,

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
źródło
Dobra uwaga, absolutnie warta odnotowania.
Grant Fritchey,
0

0023 jest liczbą, ale int i inne typy danych liczbowych nie przechowują zer wiodących, ponieważ nie ma matematycznego powodu, aby to zrobić.

Jeśli chcesz przechowywać początkowe zera, użyj ciągu danych typu, np. Char, varchar itp

Jimbo
źródło
1
Jeśli założymy, że INTma on stałą długość (jak 32 bity), a do ich przechowywania użyto zapisu binarnego, wówczas zera wiodące są rzeczywiście przechowywane. Ale nie są wyświetlane na wyjściu.
ypercubeᵀᴹ
@ypercube - Racja, ale liczba zer wiodących jest po prostu wymagana do wypełnienia 32 bitów (w przeciwieństwie do definiowalnych przez użytkownika).
Nick Chammas,
@Nick: Tak, nie kłóć się. Myślę, że nie chodzi o to, czy wiodące zera są przechowywane. Chodzi o to, czy w typie danych można zapisać dwie wersje tego samego numeru, jedną z zerami i jedną bez zer wiodących.
ypercubeᵀᴹ
Ale to nie ma sensu. Dwa dziesiętne zera wiodące absolutnie nie mają związku z liczbą wiodących zer w 32-bitowej liczbie całkowitej. Rozważmy liczbę dziesiętną 15--this zajmuje tylko jedną cyfrę w systemie szesnastkowym, F. Mają już inną liczbę „zer wiodących”. 2147483647 ma 10 cyfr, ale w zapisie szesnastkowym to tylko 7FFFFFFF lub 8 cyfr.
ErikE
Zasadniczo należy wziąć pod uwagę matematyczny system liczbowy, którego używamy ... w tym przypadku dziesiętnym (podstawa 10). 23 jest liczbą dziesiętną; to 0x1000 + 0x100 + 2x10 + 3 = 23. W ujęciu ósemkowym jest to 2X8 + 3 i tak dalej. Tak więc, mówiąc silnikowi pamięci, „przechowywanie 23 z dwoma wiodącymi zerami” nie jest przydatne, ponieważ koduje jedynie ten sam końcowy wynik, to jest 23. SQL Server nie ignoruje twoich zer, po prostu zwraca ci wartość dziesiętną równa liczbie, którą wstawiłeś, tj. 0023 lub 23.
ooutwire