SQLDeveloper查询自动填充CHAR字段
SQLDeveloper query automatic padding CHAR field
鉴于 table ATABLE
的字段 AFIELD
类型为 CHAR(8)
,并且我有一个值为 "1234567 "
[=16= 的字段]
为什么,在SQL开发者中,如果我查询:
SELECT * FROM ATABLE WHERE AFIELD = '1234567';
它会自动填充缺少的 space 和 return 结果,如果我用 :
查询
SELECT * FROM ATABLE WHERE AFIELD = :value;
并输入值,不会吗?
你是对的
SELECT * FROM ATABLE WHERE AFIELD = :value;
不能如您所愿地使用 CHAR。
无论如何,我注意到以下查询可以如您所愿地工作:
SELECT * FROM ATABLE WHERE AFIELD = &value;
如果你在多个地方使用&value,你可以在第一次使用&&value(双&)(在其他地方使用&value),
以避免多次输入相同的值;
当您必须更改该值时,您可以取消定义它:
undef value;
Within expressions and conditions, Oracle treats text literals as though they have the data type CHAR by comparing them using blank-padded comparison semantics.
当您执行 WHERE AFIELD = '1234567'
时,文本文字 '1234567'
被视为 char
并且 blank-padded comparison semantics 用于比较列值和文字。即使文字没有尾随 space,这些语义将它们视为相同,因此它找到了匹配项。
当您使用绑定变量时,您分配给它的文字是 char
,但绑定变量本身是 varchar2
- 即使您将其声明为 char
,奇怪,尽管在那种情况下该值仍然是 blank-padded:
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
绑定变量有尾随 space,长度为 8,最后一个字符为代码点 32。
当您将 char
列值与 varchar2
绑定变量进行比较时,列值是 implicitly converted 从 char
到 varchar2
:
The following rules govern implicit data type conversions:
- During SELECT FROM operations, Oracle converts the data from the column to the type of the target variable.
所以你的 space-padded char(8)
列值被隐式转换为 varchar2(8)
以匹配绑定变量的数据类型,然后因为它们是 varchar2
非填充比较语义被使用了。
当您将 char(8)
列与假定的 char(8)
绑定变量进行比较时,您实际上是在与填充的 varchar2(8)
进行比较 - 但隐式转换的列值和blank-padded 绑定变量其实是一样的,都是尾随space; '1234567 '
与 '1234567 '
相同,因此存在匹配,即使使用非填充比较语义也是如此。
使用 varchar2(8)
绑定变量会发生同样的事情,但现在绑定值 未 填充,并且因为您使用非填充比较语义来比较 '1234567 '
和 '1234567'
- 它们不相同,因此没有匹配项,查询没有返回任何数据。
正如@a_horse_with_no_name所说,你应该几乎总是使用varchar2
而不是char
。但是,如果您必须使用它并且坚持使用它,那么至少要确保您使用相同的数据类型进行比较。
鉴于 table ATABLE
的字段 AFIELD
类型为 CHAR(8)
,并且我有一个值为 "1234567 "
[=16= 的字段]
为什么,在SQL开发者中,如果我查询:
SELECT * FROM ATABLE WHERE AFIELD = '1234567';
它会自动填充缺少的 space 和 return 结果,如果我用 :
查询SELECT * FROM ATABLE WHERE AFIELD = :value;
并输入值,不会吗?
你是对的
SELECT * FROM ATABLE WHERE AFIELD = :value;
不能如您所愿地使用 CHAR。
无论如何,我注意到以下查询可以如您所愿地工作:
SELECT * FROM ATABLE WHERE AFIELD = &value;
如果你在多个地方使用&value,你可以在第一次使用&&value(双&)(在其他地方使用&value), 以避免多次输入相同的值; 当您必须更改该值时,您可以取消定义它:
undef value;
Within expressions and conditions, Oracle treats text literals as though they have the data type CHAR by comparing them using blank-padded comparison semantics.
当您执行 WHERE AFIELD = '1234567'
时,文本文字 '1234567'
被视为 char
并且 blank-padded comparison semantics 用于比较列值和文字。即使文字没有尾随 space,这些语义将它们视为相同,因此它找到了匹配项。
当您使用绑定变量时,您分配给它的文字是 char
,但绑定变量本身是 varchar2
- 即使您将其声明为 char
,奇怪,尽管在那种情况下该值仍然是 blank-padded:
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
绑定变量有尾随 space,长度为 8,最后一个字符为代码点 32。
当您将 char
列值与 varchar2
绑定变量进行比较时,列值是 implicitly converted 从 char
到 varchar2
:
The following rules govern implicit data type conversions:
- During SELECT FROM operations, Oracle converts the data from the column to the type of the target variable.
所以你的 space-padded char(8)
列值被隐式转换为 varchar2(8)
以匹配绑定变量的数据类型,然后因为它们是 varchar2
非填充比较语义被使用了。
当您将 char(8)
列与假定的 char(8)
绑定变量进行比较时,您实际上是在与填充的 varchar2(8)
进行比较 - 但隐式转换的列值和blank-padded 绑定变量其实是一样的,都是尾随space; '1234567 '
与 '1234567 '
相同,因此存在匹配,即使使用非填充比较语义也是如此。
使用 varchar2(8)
绑定变量会发生同样的事情,但现在绑定值 未 填充,并且因为您使用非填充比较语义来比较 '1234567 '
和 '1234567'
- 它们不相同,因此没有匹配项,查询没有返回任何数据。
正如@a_horse_with_no_name所说,你应该几乎总是使用varchar2
而不是char
。但是,如果您必须使用它并且坚持使用它,那么至少要确保您使用相同的数据类型进行比较。