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

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)?

user8365
источник
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'
a1ex07
источник
Хороший момент, абсолютно стоит отметить.
Грант Фричей
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