SQLDeveloper查询自动填充CHAR字段

时间:2017-02-03 12:43:13

标签: oracle oracle-sqldeveloper

鉴于表格ATABLE的字段AFIELD类型为CHAR(8),其中我的字段值为"1234567 "

为什么,在SQL Developer中,如果我查询:

SELECT * FROM ATABLE WHERE AFIELD = '1234567';

它将自动填充缺失的空格并返回结果,如果我查询:

SELECT * FROM ATABLE WHERE AFIELD = :value;

并输入值,它不会?

2 个答案:

答案 0 :(得分:1)

你是对的

SELECT * FROM ATABLE WHERE AFIELD = :value;

不能按照您的意愿使用CHAR。

无论如何,我注意到以下查询可以按您的方式工作:

SELECT * FROM ATABLE WHERE AFIELD = &value;

如果你在几个地方使用& value,你可以第一次使用&& value(double&)(和其他地方的&值), 为了避免多次输入相同的值; 当您必须更改该值时,您可以使用以下内容取消定义:

undef value;

答案 1 :(得分:1)

From the documentation

  

在表达式和条件中,Oracle通过使用空白填充的比较语义来比较文本文字,就好像它们具有数据类型CHAR一样。

执行WHERE AFIELD = '1234567'时,文字文字'1234567'被视为charblank-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绑定变量进行比较时,列值为charvarchar2char(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。但是如果你必须使用它并坚持使用它,那么至少要确保使用相同的数据类型进行比较。