Ren*_*ger 12 oracle plsql oracle11gr2
以下是一些PL/SQL代码的摘录,我相信这些代码演示了PL/SQL错误:
if guid_ is null then
dbms_output.put_line('guid_ is null: ' || guid_);
end if;
Run Code Online (Sandbox Code Playgroud)
执行这些行时,将打印
guid_ is null: 07D242FCC55000FCE0530A30D4928A21
Run Code Online (Sandbox Code Playgroud)
我在Oracle 11R2上
select * from v$version;
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
Run Code Online (Sandbox Code Playgroud)
我可以使用以下类型和匿名块重现这一点.对不起,但我相信我不能再缩短它了:
create type tq84_t as table of varchar2(32);
/
create type tq84_o as object (
dummy number(1),
not final member procedure clear
) not final;
/
show errors
create type tq84_d under tq84_o (
g varchar2(32),
constructor function tq84_d return self as result,
overriding member procedure clear
);
/
show errors
create package tq84_h as
t tq84_t;
end tq84_h;
/
show errors
create package body tq84_h as
begin
t := tq84_t();
end;
/
show errors
create type body tq84_o as
member procedure clear is begin
null;
end clear;
end;
/
create type body tq84_d as
constructor function tq84_d return self as result is
begin
g := sys_guid;
return;
end tq84_d;
overriding member procedure clear is begin
tq84_h.t.extend;
tq84_h.t(tq84_h.t.count) := g;
g := null;
end clear;
end;
/
show errors
declare
b tq84_o; -- Change to tq84_d ...
guid_ varchar2(32);
begin
b := new tq84_d;
guid_ := treat(b as tq84_d).g;
b.clear;
if guid_ is null then
dbms_output.put_line('guid_ is null: ' || guid_);
end if;
end;
/
drop type tq84_t;
drop type tq84_d;
drop type tq84_o;
drop package tq84_h;
Run Code Online (Sandbox Code Playgroud)
另请注意,当我更改b tq84_o为时b tq84_d,错误不再发生.
有人可以验证这是否也发生在其他系统上?
对我来说这是一个错误。在 中,IF变量的guid_处理方式与 的字符串连接中的处理方式不同put_line。我觉得奇怪的是,在b.clear 声明生效之前is null:
declare
b tq84_o; -- Change to tq84_d ...
guid_ varchar2(32);
begin
b := new tq84_d;
guid_ := treat(b as tq84_d).g;
if guid_ is null then
dbms_output.put_line('before clear: guid_ is null: ' || guid_);
end if;
b.clear;
if guid_ is null then
dbms_output.put_line('after clear: guid_ is null: ' || guid_);
end if;
end;
/
Run Code Online (Sandbox Code Playgroud)
输出:
after clear: guid_ is null: 07D43ACB728A2173E054A0481C66CF28
Run Code Online (Sandbox Code Playgroud)
我解决了从函数返回 GUID 时的问题:
declare
b tq84_o; -- Change to tq84_d ...
guid_ varchar2(32);
function get_guid
return varchar2 is
begin
return treat(b as tq84_d).g;
end;
begin
b := new tq84_d;
guid_ := get_guid; -- treat(b as tq84_d).g;
if guid_ is null then
dbms_output.put_line('before clear: guid_ is null: ' || guid_);
end if;
b.clear;
if guid_ is null then
dbms_output.put_line('after clear: guid_ is null: ' || guid_);
end if;
end;
/
Run Code Online (Sandbox Code Playgroud)
上面的代码没有进入任何一个if guid_ is null. 所以对我来说这证明了这一点:
这是一个错误。