鉴于表格ATABLE
的字段AFIELD
类型为CHAR(8)
,其中我的字段值为"1234567 "
为什么,在SQL Developer中,如果我查询:
SELECT * FROM ATABLE WHERE AFIELD = '1234567';
它将自动填充缺失的空格并返回结果,如果我查询:
SELECT * FROM ATABLE WHERE AFIELD = :value;
并输入值,它不会?
答案 0 :(得分:1)
你是对的
SELECT * FROM ATABLE WHERE AFIELD = :value;
不能按照您的意愿使用CHAR。
无论如何,我注意到以下查询可以按您的方式工作:
SELECT * FROM ATABLE WHERE AFIELD = &value;
如果你在几个地方使用& value,你可以第一次使用&& value(double&)(和其他地方的&值), 为了避免多次输入相同的值; 当您必须更改该值时,您可以使用以下内容取消定义:
undef value;
答案 1 :(得分:1)
在表达式和条件中,Oracle通过使用空白填充的比较语义来比较文本文字,就好像它们具有数据类型CHAR一样。
执行WHERE AFIELD = '1234567'
时,文字文字'1234567'
被视为char
,blank-padded comparison semantics用于比较列值和文字。尽管文字没有尾随空格,但这些语义看起来是相同的,所以它找到了匹配。
当你使用绑定变量时,你赋给它的文字是char
,但绑定变量本身是varchar2
- 即使你把它声明为char
,奇怪的是,虽然在这种情况下,该值仍为空白填充:
var char_value char(8);
exec :char_value := '1234567';
var varchar2_value varchar2(8);
exec :varchar2_value := '1234567';
select dump('1234567') as d1, dump(:char_value) as d2, dump(:varchar2_value) as d3
from dual;
D1 D2 D3
------------------------------------ ------------------------------------ ------------------------------------
Typ=96 Len=7: 49,50,51,52,53,54,55 Typ=1 Len=8: 49,50,51,52,53,54,55,32 Typ=1 Len=7: 49,50,51,52,53,54,55
文本文字是data type 96 (char
),而两个绑定变量都是类型1(varchar
/ varchar2
);但请注意char_value
绑定变量具有尾随空格,长度为8,最后一个字符为代码点32。
当您将char
列值与varchar2
绑定变量进行比较时,列值为char
从varchar2
到char(8)
:
以下规则管理隐式数据类型转换:
- 在SELECT FROM操作期间,Oracle将列中的数据转换为目标变量的类型。
因此,您的空格填充varchar2(8)
列值会隐式转换为varchar2
以匹配绑定变量的数据类型,然后因为它们是char(8)
非填充比较语义使用。
当您将char(8)
列与所谓的varchar2(8)
绑定变量进行比较时,您实际上正在与填充的'1234567 '
进行比较 - 但是隐式转换的列值和空白填充的绑定变量实际上是相同的,都带有尾随空格; '1234567 '
与varchar2(8)
相同,因此即使使用非填充比较语义也存在匹配。
使用'1234567 '
绑定变量会发生相同的事情,但现在绑定的值是而不是填充,并且正如您使用非填充比较语义来比较'1234567'
和{ {1}} - 它们不相同,因此没有匹配项,查询也不会返回任何数据。
正如@a_horse_with_no_name所说,你应该几乎总是使用varchar2
而不是char
。但是如果你必须使用它并坚持使用它,那么至少要确保使用相同的数据类型进行比较。