Oracle -为什么CHAR列是自动添加前导零?



我正在使用Oracle DB 11g

我有一个数据库表,主键是CHAR(4) -尽管只有数字用于该列。

我注意到有一些记录,例如显示'0018'或'0123'。

我注意到一些奇怪的事情,需要一些帮助

- CHAR列是否"自动"把0加到一个值上?

-我也注意到,当写一个SQL,如果我不使用引号在我的where子句,它返回结果,但如果我使用引号它不?例如

DB CHAR(4)列的键为'0018'

我使用这个查询

SELECT * FROM TABLE_A WHERE COLUMN_1=18;

我得到了预期的行。

但是当我尝试下面的

SELECT * FROM TABLE_A WHERE COLUMN_1='18';

这个不工作,但这个可以再次工作

SELECT * FROM TABLE_A WHERE COLUMN_1='0018';

所以我有点困惑如何第一个查询可以工作如预期没有引号?

CHAR列是否"自动";把0加到一个值上?

。来自文档:

如果插入的值小于列长度,Oracle会将该值空填充为列长度。

因此,如果您插入数字18,它将隐式转换为字符串'18 ',后面有两个空格。您可以在这个小提琴中看到这一点,它也显示了比较。

这意味着其他的东西是零填充你的数据-要么是你的应用程序/代码插入之前,或可能在一个触发器。

我也注意到,当写一个SQL,如果我不使用引号在我的where子句,它返回的结果,但如果我使用引号它不

数据类型比较和转换规则也在文档中显示:

当比较字符值和数值时,Oracle将字符数据转换为数值。

当你这样做的时候:

SELECT * FROM TABLE_A WHERE COLUMN_1=18;

字符串'0018'隐式地转换为数字18,以便它可以与您的数字文字进行比较。转换后,前导零是没有意义的,因此'0018','018 '18'都将匹配。

与您的零填充列值匹配,您确实得到一个结果:18('0018'转换为数字)=18

这意味着表中的每个值在进行比较之前必须进行转换;这也意味着如果你在column_1上有一个正常的索引,那么它就不会在比较中使用。

当你这样做的时候:

SELECT * FROM TABLE_A WHERE COLUMN_1='18';

列和文字是相同的数据类型,因此不需要应用转换(因此可以使用普通索引)。Oracle将在这里使用空白填充比较语义,因为列是char,将较短的文字值填充到列大小为'18 ',然后只有在字符串完全匹配时才会匹配-所以'18 '会匹配,但'0018'' 18 '或其他任何东西都不会匹配。

与您的零填充列值不匹配,您没有得到结果:'0018'!='18 '('18'填充到长度4)

当你这样做的时候:

SELECT * FROM TABLE_A WHERE COLUMN_1='0018';

列和字面值是相同的数据类型,所以没有转换,没有填充应用,因为字面值已经与列值相同的长度,并且它只会在字符串完全匹配时匹配-所以'0018'会匹配,但'18 '' 18 '或其他任何东西都不会匹配。

与您的零填充列值匹配,您确实得到一个结果:'0018'='0018'

CHAR列是否"自动";把0加到一个值上?

不总是0,有时是空格。如果所有字符值都是数字,则将在字符字段的固定大小之前填充零。

所以我有点困惑如何第一个查询可以工作如预期没有引号?

由于隐式类型转换。系统将char转换为数字或将数字转换为char,在这种情况下,它要么去掉前导零并比较数字值,要么填充为相同的数据类型,然后进行比较。我很确定它将字符转换为数字,因此在比较时将前导零删除。

参见:https://docs.oracle.com/cd/B13789_01/server.101/b10759/sql_elements002.htm获取更多关于数据类型比较和隐式强制转换的详细信息

:

  • in the case: SELECT * FROM TABLE_A WHERE COLUMN_1='18';我认为18已经是一个字符数据,所以它变成了'18 '(注意18后面有2个空格)与'0018'相比
  • select * from table_a where column_1 =18;columN_1被强制转换为数字,所以18=18
  • select * from table_a where column_1 ='0018';column_1已经是一个char(4),所以'0018' = '0018'

相关内容

  • 没有找到相关文章

最新更新