显然oracle似乎没有区分空字符串和空值。例如。
Select name from TABLE_A where id=100;
ID NAME
100 null
Update TABLE_A set NAME='' where id=100;
SELECT -->
ID NAME
100 null
SELECT length(NAME) FROM TABLE_A WHERE id=100;
null
我想不出有什么理由可以建立Oracle以这种方式运行(它是否也在sqlplus中执行此操作? - 我通过java接口访问,引用的文章使用了php客户端)。
难道你至少不想区分0长度和未定义长度吗?这是一个已知的问题?某些特定目的的故意行为?数据库理论中长期存在的争议?是什么赋予了?
(这是由Matt Solnit对this question的回答提示的。)
答案 0 :(得分:33)
Oracle
非常非常老。
回到80's
开发时(在有任何标准之前),他们认为这是一个好主意,然后给出Oracle
存储其值的方式,它确实是。
以下是Oracle
存储数据的方式(取自documentation):
数据中没有存储数据类型,只存储数据长度和数据本身。
如果NULL
发生在具有值的两列之间,则它存储为单个字节,意味着列的长度为0
(实际上为0xFF
)。结尾NULL
根本不存储。
因此要存储值'test'
,Oracle
需要存储5个字节:04 74 65 73 74
。
但是,要存储空字符串和NULL
,Oracle
只需要将数据长度设置为0
。
如果您的数据要存储在每个价格20 Mb
的{{1}}个硬盘上,那就太聪明了。
后来,当标准出现时,它不再是一个好主意了,但那时已经有很多很多代码依赖于5,000$
和NULL
是同一个东西。
让''
进行此类区分会破坏吨代码。
要解决此问题,他们会将VARCHAR
重命名为VARCHAR
(这不是任何标准的一部分),并指出VARCHAR2
将从不区分VARCHAR2
和一个空字符串,并敦促每个人使用此数据类型。
现在他们可能正在等待使用NULL
数据库中VARCHAR
的最后一个人死亡。
答案 1 :(得分:3)
你可能想在两年多前在OTN上阅读这篇关于这个确切主题的长篇有趣的讨论:http://forums.oracle.com/forums/thread.jspa?threadID=456874&start=0&tstart=0
此致 罗布。
答案 2 :(得分:1)
这就是为什么像Date这样聪明的人会说你永远不应该使用空值。
(不,我必须准确。实际上,这只是他过去几十年来提到的支持这一说法的几百个理由中的一个。)
修改
我其实也想回应这个:
“让VARCHAR做这样的区分会打破大量的代码。”
是的,当然,通过在每次更新时将“空字符串”替换为空来至少打破标准的精神是一个较小的邪恶?
(注意:null不等于任何东西,甚至不是自己,所以在将空字符串分配给列后,oracle会在该列中为您提供一个与您想要的值不同的值出现在那里。哇。)
答案 3 :(得分:0)
看起来Oracle已经说过,这种行为可能会在将来的版本中发生变化。什么时候释放它将被提及。
如果您有权访问metalink,请查看注释:1011340.6(遗憾的是,由于限制,我无法复制此处注释的内容)
如果您无法访问metalink,请查看10g第2版文档中的以下内容here
答案 4 :(得分:0)
@Ian,回复你。
Oracle触发器可以引用它们创建的表:
create table t (id number(10) );
create or replace trigger t_bir before insert on t for each row
declare
l_id t.id%type;
begin
select id
into l_id
from t
where id = :new.id;
exception
when no_data_found then
null;
end;
/
SQL> insert into t values (20);
1 row is created.
SQL> select * from t;
ID
----------
20