Как сохранить лидирующие нули при вставке числа в эту таблицу? [закрыто]


10

Я вставил две записи в таблицу.

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

Когда я запрашиваю их, они все отображаются как 23. Это означает, что SQL Server игнорирует ведущие нули. Какой механизм стоит за этим? Как я могу заставить SQL Server возвращать значения, когда я их вставил (то есть 0023и 23)?


2
Почему вы заботитесь о ведущих нулях? Если они имеют значение для вашей системы, то они idдолжны быть типа VARCHARили аналогичными.
Ник Чаммас

Как именно вы ожидаете, что 0023 будет закодировано в базе данных как нечто отличное от 23 или 023 или 0000000023? Все они представляют один и тот же номер. И int это тип данных NUMBER. Сервер не может хранить это значение «ведущего числа десятичных нулей».
ErikE

Это плохой вопрос, и он был бы рассмотрен в любом введении в класс программирования. Int никогда не может хранить начальные нули из-за природы int. Это можно решить, посмотрев на любое количество веб-ресурсов. Это не требует ввода администратора базы данных.
Jcolebrand

1
Ведущие нули подразумеваются. Помимо использования строки вместо этого, если вам нужно определенное количество лидирующих нулей, это дополнительная информация помимо того, что хранится в столбце int. Один из вариантов - использование строкового столбца, а другой - сохранение числа начальных нулей в другом столбце или в пользовательском интерфейсе. например, если пользовательский интерфейс всегда форматируется до 4 цифр с добавлением начальных нулей, то вы сохранили эту информацию в пользовательском интерфейсе. Если вам нужно, чтобы число нулей изменялось и сохранялось для каждой записи, вы можете хранить эту информацию в отдельном поле.
Дейв Кузино

Ответы:


27

0023это не число. Это строка. 23это номер. SQL Server может распознать, что эти дополнительные нули не нужны для определения числа, поэтому он игнорирует их. Если вы хотите отобразить в приложении значение как 0023, я бы предложил выполнить форматирование на стороне приложения. Таким образом, число, хранящееся в SQL Server, остается числом, если вы хотите выполнить сложение, агрегирование или другие вычисления. Если вам действительно нужно сохранить его как ' 0023', вам нужно преобразовать его в символьное поле; чар, варчар, нварчар, нчар.


Если 0023 является строкой, как я могу вставить значение в таблицу, для которой я определил идентификатор как формат int?
user8365

@ user8365 - Либо определите idкак, VARCHARлибо просто вставьте 23 вместо 0023
Ламак

5
@ user8365 - Вы спрашиваете, можете ли вы заставить SQL Server нарушать целостность домена этого поля. Ты не можешь Если 0023это строка, то сохраните ее как строку. Если это не так, сохраните его как INT и забудьте о ведущих нулях.
Ник Чаммас

Именно то, что сказал @NickChammas. У вас нет выбора здесь. 23 - это число, 0023 - это строка. Если вы хотите число, относитесь к нему как к числу. Как говорится в моем ответе, если ему нужно отсортировать как число, сложить, вычесть, умножить, разделить и т. Д., Как число, то это должен быть номер. Нет выбора. Нет аргументов. Ведущие нули - это просто форматирование. Сделайте это в коде приложения или где-то еще.
Грант Фричей

@ Грант Я не могу согласиться с тем, что ведущие нули просто форматирование. Они законны в любой системе счисления; однако 0023b10 = 23b10; поэтому любая система хранения получает некоторую степень сжатия, поскольку не кодирует все ведущие нули. Итак, в основном наш спрашивающий задает не тот вопрос. Почему 0023 не является целым числом? Это целое число! Нам просто не нужно кодировать бесконечность лидирующих чисел, чтобы представлять их как таковые.
ooutwire

5

В других ответах уже говорилось, что 00023это число; Я просто хочу добавить, что вы можете использовать вычисляемые столбцы, чтобы показать это число в произвольном формате. Например,

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'

Хороший момент, абсолютно стоит отметить.
Грант Фричей

0

0023 - это число, но типы данных int и другие числа не хранят начальные нули, поскольку для этого нет математической причины.

Если вам нужно хранить начальные нули, используйте строковый тип данных, например, char, varchar и т. Д.


1
Если мы предположим, что INTэто фиксированная длина (например, 32 бита) и двоичная запись используется для их хранения, тогда начальные нули действительно сохраняются. Но они не отображаются в выводе.
ypercubeᵀᴹ

@ypercube - Верно, но число начальных нулей - это просто то, что требуется для заполнения 32 бит (в отличие от определяемого пользователем).
Ник Чаммас

@ Ник: Да, не спорь там. Я думаю, дело не в том, сохранены ли ведущие нули. Вопрос о том, могут ли две версии одного и того же номера быть сохранены в типе данных, одна с первым и одна без начальных нулей.
ypercubeᵀᴹ

Но это не имеет смысла. Два десятичных начальных нуля не имеют абсолютно никакого отношения к числу ведущих нулей в 32-разрядном целом числе. Рассмотрим десятичное число 15--this занимает одну цифру в шестнадцатиричное F. У них уже есть другое количество «ведущих нулей». 2147483647 - это 10 цифр, но в шестнадцатеричном формате это только 7FFFFFFF или 8 цифр.
ErikE

По сути, нужно рассмотреть математическую систему счисления, которую мы используем ... в данном случае десятичную (основание 10). 23 - десятичное число; это 0x1000 + 0x100 + 2x10 + 3 = 23. В восьмеричном виде это 2X8 + 3 и так далее. Таким образом, сказать механизму хранения «хранилище 23 с двумя ведущими нулями» бесполезно, поскольку он просто кодирует один и тот же конечный результат, то есть 23. SQL Server не игнорирует ваши нули, он просто возвращает вам десятичное значение равно номеру, который вы вставили, т.е. 0023 или 23.
ooutwire
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.