在表中插入数字时,如何保留前导零?[关闭]


10

我已将两个记录插入到表中。

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

当我查询它们时,它们都显示为23。这意味着SQL Server忽略前导0。其背后的机制是什么?在插入值时,SQL Server如何返回值(即002323)?


2
您为什么关心前导零?如果它们对您的系统有意义,id则应为类型VARCHAR或类似类型。
Nick Chammas 2012年

您究竟如何期望0023在数据库中编码为不同于23或023或0000000023的内容?它们都代表相同的NUMBER。而int是NUMBER数据类型。服务器没有位置存储此“十进制零的前导数”值。
ErikE 2012年

这是一个很糟糕的问题,任何编程类的介绍都将涵盖这个问题。由于int的性质,int永远无法存储前导零。这可以通过查看任意数量的Web资源来解决。这不需要数据库管理员的输入。
jcolebrand

1
隐含前导零。除了使用字符串之外,如果需要特定数量的前导零,那么这是除int列中存储的信息以外的其他信息。一种选择是使用字符串列,而另一种选择是将前导零的数目存储在另一列或用户界面中。例如,如果UI始终格式化为4位数字,并以零开头的填充,则表明您已将此信息存储在UI中。如果您需要零位数来变化并为每个记录保留,您可以将该信息存储在单独的字段中。
Dave Cousineau

Answers:


27

0023不是数字。这是一个字符串。23是数字。SQL Server能够识别出不需要额外的零来定义数字,因此它会忽略它们。如果要向应用程序显示0023的值,建议在应用程序端进行格式化。这样,如果要进行加法,聚合或其他计算,则存储在SQL Server中的数字仍然是数字。如果确实需要将其存储为“ 0023”,则需要将其转换为字符字段。char,varchar,nvarchar,nchar。


如果0023是字符串,如何将值插入到将ID定义为int格式的表中?
user8365 2012年

@ user8365 -无论是定义idVARCHAR或刚插入23,而不是0023
Lamak

5
@ user8365-您正在询问是否可以使SQL Server违反该字段的域完整性。你不能 如果0023为字符串,则将其存储为字符串。如果不是,则将其存储为INT并忽略前导零。
Nick Chammas 2012年

正是@NickChammas所说的。您在这里别无选择。23是数字,0023是字符串。如果需要数字,请将其视为数字。就像我的回答所说,如果它需要像数字一样排序,加,减,乘,除等,就像一个数字,那么它就必须是一个数字。别无选择。没有参数。前导零只是格式化。在应用代码或其他地方执行此操作。
Grant Fritchey 2012年

@格兰特,我不能同意前导零只是格式化。它们在任何数字系统中都是合法的;但是0023b10 = 23b10; 因此,任何存储系统都不会对所有前导零进行编码,从而获得一定程度的压缩。因此,从根本上说,我们的提问者在问一个错误的问题。为什么0023不是整数?是整数!我们只需要编码无穷大的前导数字就可以这样表示。
ooutwire 2012年

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'

好点,绝对值得注意。
Grant Fritchey 2012年

0

0023是一个数字,但是int和其他number数据类型不存储前导零,因为没有数学上的理由。

如果您需要存储前导零,请使用字符串数据类型,例如char,varchar等


1
如果我们假设它INT是固定长度的(例如32位),并且使用二进制表示法来存储它们,那么确实存储了前导零。但是它们不会显示在输出中。
ypercubeᵀᴹ

@ypercube-是的,但是前导零的数目仅仅是填充32位(与用户定义相反)所需要的。
Nick Chammas 2012年

@尼克:是的,在那里没有争论。我认为关键不在于是否存储前导零。这是是否可以将相同编号的两个版本存储在数据类型中,一个带前导零,一个不带前导零。
ypercubeᵀᴹ

但这是没有道理的。两个十进制前导零绝对与32位整数中的前导零数目没有关系。考虑十进制数- 15这仅需要十六进制数一位F。它们已经具有不同数量的“前导零”。2147483647是10位数字,但以十六进制表示的只有7FFFFFFF或8位数字。
ErikE 2012年

从根本上讲,必须考虑我们正在使用的数学数字系统...在这种情况下为十进制(基数为10)。23是十进制数;它是0x1000 + 0x100 + 2x10 + 3 =23。在八进制中,它是2X8 + 3,依此类推。因此,对存储引擎来说,“存储带有两个前导零的23”是没有用的,因为它只编码相同的最终结果,即23。SQLServer不会忽略您的零,它只会向您返回一个十进制值等于其中插入的数量,即,0023或23
ooutwire
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.