Here's an excerpt from some PL/SQL code that I believe demonstrates a PL/SQL bug:
if guid_ is null then
dbms_output.put_line('guid_ is null: ' || guid_);
end if;
When these lines are executed, it prints
guid_ is null: 07D242FCC55000FCE0530A30D4928A21
I am on 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
I can reproduce this with the following types and anonymous block. Sorry for the length, but I believe I cannot shorten it any more:
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;
Note also, that when I change b tq84_o
to b tq84_d
, the error does not occur anymore.
Can someone verify if this is happening on other systems as well?
PL/SQL warning messages all use the prefix PLW .
The answer is that PL/SQL is not growing, but not going away either. Because it is used in the Oracle database, and the Oracle database is a fixture of enterprise systems world-wide, it will outlive you. High-performance batch processing has to happen close to the data, so PL/SQL will continue to rule in this area.
An exception is a PL/SQL error that is raised during program execution, either implicitly by TimesTen or explicitly by your program. Handle an exception by trapping it with a handler or propagating it to the calling environment.
Q: Which is better: SQL or PL/SQL? PL/SQL is an extension of SQL and further includes many procedural features like function, data variables, exception handling, and triggers. Moreover, PL/SQL allows us to transfer an entire block of statements to the database at once whereas SQL executes a single query at a time.
To me this is a bug. In the IF
the variable guid_
is not treated the same as in the the string concatenation for the put_line
. What I find strange is that before the b.clear
statement the is null
works:
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;
/
Output:
after clear: guid_ is null: 07D43ACB728A2173E054A0481C66CF28
I workaround the problem when returning the GUID from a function:
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;
/
The above code does not go into neither of the if guid_ is null
. So to me this proves it:
This is a bug.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With