问题描述
希亚,汤姆斯
我偶然发现了一件我觉得有点奇怪的事情。我在LiveSQL做了这个测试脚本:
当我选择CH列的转储时,我得到的预期输出都是10个字符长 (米奇加4个空格。)
当我选择VC列的转储时,我还分别得到6、8和10个字符的预期输出。
join返回意外输出 (至少对我来说是意外的;-)
首先,使用空白填充的比较语义执行联接比较。文档 (http://docs.oracle.com/database/122/SQLRF/Data-Type-Comparison-Rules.htm#GUID-A114F1F4-A08D-4107-B679-323DC7FEA31C) 在数据类型比较规则状态:
“仅当比较中的两个值都是数据类型CHAR,NCHAR,文本文字或用户函数返回的值的表达式时,Oracle才使用空白填充的比较语义。”
“每当比较中的一个或两个值具有数据类型VARCHAR2或nvarchar2时,Oracle都会使用非填充比较语义。”
由于我的一个值是VARCHAR2,我期望非填充比较语义,所以只有每个表的第三行将被连接。但它使用的是连接所有三行的空白填充比较语义。
可能是-可能是文档错误。(或者我误读了文档,并且在其他地方说明了如何执行此联接。)
因此,出于比较目的,它将空格附加到VC值,以便将它们与CH值进行比较。但是,当我然后选择VC值时,我没有得到存储在VC列中的实际数据,我得到了 “比较值”-带有附加空格的VC值。
这是预期的行为吗?
谢谢
啦啦队
/金
我偶然发现了一件我觉得有点奇怪的事情。我在LiveSQL做了这个测试脚本:
create table ch ( ch char(10) ); create table vc ( vc varchar2(10) ); insert into ch values ('MICKEY'); insert into ch values ('MICKEY '); insert into ch values ('MICKEY '); insert into vc values ('MICKEY'); insert into vc values ('MICKEY '); insert into vc values ('MICKEY '); commit; select ch, dump(ch) as ch_dump from ch; select vc, dump(vc) as vc_dump from vc; select ch, dump(ch) as ch_dump , vc, dump(vc) as vc_dump from ch join vc on vc.vc = ch.ch;复制
当我选择CH列的转储时,我得到的预期输出都是10个字符长 (米奇加4个空格。)
CH CH_DUMP MICKEY Typ=96 Len=10: 77,73,67,75,69,89,32,32,32,32 MICKEY Typ=96 Len=10: 77,73,67,75,69,89,32,32,32,32 MICKEY Typ=96 Len=10: 77,73,67,75,69,89,32,32,32,32复制
当我选择VC列的转储时,我还分别得到6、8和10个字符的预期输出。
VC VC_DUMP MICKEY Typ=1 Len=6: 77,73,67,75,69,89 MICKEY Typ=1 Len=8: 77,73,67,75,69,89,32,32 MICKEY Typ=1 Len=10: 77,73,67,75,69,89,32,32,32,32复制
join返回意外输出 (至少对我来说是意外的;-)
CH CH_DUMP VC VC_DUMP MICKEY Typ=96 Len=10: 77,73,67,75,69,89,32,32,32,32 MICKEY Typ=1 Len=10: 77,73,67,75,69,89,32,32,32,32 MICKEY Typ=96 Len=10: 77,73,67,75,69,89,32,32,32,32 MICKEY Typ=1 Len=10: 77,73,67,75,69,89,32,32,32,32 MICKEY Typ=96 Len=10: 77,73,67,75,69,89,32,32,32,32 MICKEY Typ=1 Len=10: 77,73,67,75,69,89,32,32,32,32复制
首先,使用空白填充的比较语义执行联接比较。文档 (http://docs.oracle.com/database/122/SQLRF/Data-Type-Comparison-Rules.htm#GUID-A114F1F4-A08D-4107-B679-323DC7FEA31C) 在数据类型比较规则状态:
“仅当比较中的两个值都是数据类型CHAR,NCHAR,文本文字或用户函数返回的值的表达式时,Oracle才使用空白填充的比较语义。”
“每当比较中的一个或两个值具有数据类型VARCHAR2或nvarchar2时,Oracle都会使用非填充比较语义。”
由于我的一个值是VARCHAR2,我期望非填充比较语义,所以只有每个表的第三行将被连接。但它使用的是连接所有三行的空白填充比较语义。
可能是-可能是文档错误。(或者我误读了文档,并且在其他地方说明了如何执行此联接。)
因此,出于比较目的,它将空格附加到VC值,以便将它们与CH值进行比较。但是,当我然后选择VC值时,我没有得到存储在VC列中的实际数据,我得到了 “比较值”-带有附加空格的VC值。
这是预期的行为吗?
谢谢
啦啦队
/金
专家解答
我想你已经过度考虑了这个金;)
So for comparison purposes it is appending spaces to the VC values in order to compare them with the CH values. But when I then SELECT the VC values, I do not get the actual data stored in the VC column, I get the "comparison value" - the VC value with appended spaces.
不要。
最后一个插入在VC列中存储附加空格的值。你说过 “这个字符串的末尾有空格”。所以它有十个字符。数据库会自动将这些空格附加到所有char值的末尾。
所以对于最后一列VC,你are比较存储的值
(VC) “米奇” 到 (CH) “米奇”
将ID列添加到表中可能会使此更容易看到:
如果将char转换为连接中的较短的varchar2,它将修剪末端的空格。它只与您存储在VC中具有该长度的行匹配:
如果你把VC转换为char,你会得到九行:
So for comparison purposes it is appending spaces to the VC values in order to compare them with the CH values. But when I then SELECT the VC values, I do not get the actual data stored in the VC column, I get the "comparison value" - the VC value with appended spaces.
不要。
最后一个插入在VC列中存储附加空格的值。你说过 “这个字符串的末尾有空格”。所以它有十个字符。数据库会自动将这些空格附加到所有char值的末尾。
所以对于最后一列VC,你are比较存储的值
(VC) “米奇” 到 (CH) “米奇”
将ID列添加到表中可能会使此更容易看到:
create table ch ( chid int, ch char(10) ); create table vc ( vcid int, vc varchar2(10) ); insert into ch values (1, 'MICKEY'); insert into ch values (2, 'MICKEY '); insert into ch values (3, 'MICKEY '); insert into vc values (4, 'MICKEY'); insert into vc values (5, 'MICKEY '); insert into vc values (6, 'MICKEY '); commit; select chid, vcid, ch, vc from ch join vc on vc.vc = ch.ch; CHID VCID CH VC 3 6 MICKEY MICKEY 2 6 MICKEY MICKEY 1 6 MICKEY MICKEY复制
如果将char转换为连接中的较短的varchar2,它将修剪末端的空格。它只与您存储在VC中具有该长度的行匹配:
select chid, vcid, ch, vc from ch join vc on vc.vc = cast(ch.ch as varchar2(8)); CHID VCID CH VC 3 5 MICKEY MICKEY 2 5 MICKEY MICKEY 1 5 MICKEY MICKEY select chid, vcid, ch, vc from ch join vc on vc.vc = cast(ch.ch as varchar2(7)); no rows selected复制
如果你把VC转换为char,你会得到九行:
select chid, vcid, ch, vc from ch join vc on cast(vc.vc as char(10)) = ch.ch; CHID VCID CH VC 3 4 MICKEY MICKEY 2 4 MICKEY MICKEY 1 4 MICKEY MICKEY 3 5 MICKEY MICKEY 2 5 MICKEY MICKEY 1 5 MICKEY MICKEY 3 6 MICKEY MICKEY 2 6 MICKEY MICKEY 1 6 MICKEY MICKEY复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
【专家有话说第五期】在不同年龄段,DBA应该怎样规划自己的职业发展?
墨天轮编辑部
1442次阅读
2025-03-13 11:40:53
Oracle RAC ASM 磁盘组满了,无法扩容怎么在线处理?
Lucifer三思而后行
877次阅读
2025-03-17 11:33:53
RAC 19C 删除+新增节点
gh
537次阅读
2025-03-14 15:44:18
2月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
492次阅读
2025-03-13 14:38:19
Oracle 如何修改 db_unique_name?强迫症福音!
Lucifer三思而后行
424次阅读
2025-03-12 21:27:56
Oracle DataGuard高可用性解决方案详解
孙莹
363次阅读
2025-03-26 23:27:33
墨天轮个人数说知识点合集
JiekeXu
310次阅读
2025-04-01 15:56:03
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
277次阅读
2025-04-08 09:12:48
风口浪尖!诚通证券扩容采购Oracle 793万...
Roger的数据库专栏
265次阅读
2025-03-24 09:42:53
切换Oracle归档路径后,不能正常删除原归档路径上的归档文件
dbaking
264次阅读
2025-03-19 14:41:51