PL/SQL 버그입니까?
다음은 PL/SQL 코드에서 발췌한 것으로 PL/SQL 버그를 보여줍니다.
if guid_ is null then
dbms_output.put_line('guid_ is null: ' || guid_);
end if;
이 선들이 실행되면, 그것은 인쇄됩니다.
guid_ is null: 07D242FCC55000FCE0530A30D4928A21
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
저는 다음 유형과 익명 블록으로 이것을 재현할 수 있습니다.길이가 길어서 죄송합니다만, 더 이상 줄일 수 없을 것 같습니다.
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;
참고로, 내가 바뀔 때.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;
/
출력:
after clear: guid_ is null: 07D43ACB728A2173E054A0481C66CF28
함수에서 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;
/
위의 코드는 다음 중 어느 것에도 들어가지 않습니다.if guid_ is null
그래서 저는 이것이 증명합니다.
이것은 벌레입니다.
그것은 오라클 버그처럼 보입니다.Oracle Enterprise 11.2.0.3.0(64비트) 인스턴스에서도 동일한 현상이 나타납니다.
조금만 가지고 놀고 나니, 벌레가 있는 것이 꽤 분명합니다.if
조건:guid_ is null
값이 포함되어 있더라도 참으로 평가됩니다.
에 대한 나의 이전 의견.else
더 이상 사실이 아닌 것 같습니다.실수로 테스트 스크립트를 변경했거나 버그를 예측할 수 없습니다.
저는 믿을 만하게 만드는 것 같습니다.else
시나리오 작업은 다음 단계를 따릅니다.
- 변경할 내용
if
대상:
if guid_ is null then dbms_output.put_line('guid_ is null: ' || guid_); else dbms_output.put_line('guid_ is not null: ' || guid_); end if;
- 스크립트를 실행합니다. 출력은 null 메시지를 반환합니다.
- 선언 변경 위치
tq84_o
로.tq84_d
. - 스크립트를 실행합니다. 출력에서 null이 아닌 메시지가 반환됩니다.
- 선언을 다시 다음으로 변경
tq84_o
. - 스크립트를 실행합니다. 출력에서 null이 아닌 메시지가 반환됩니다.
이 프로세스의 결과는 다음과 같습니다.
guid_ is null: 07D41C8BCE696EA3E0539014190A7DA0
guid_ is not null: 07D41C8BCE7D6EA3E0539014190A7DA0
guid_ is not null: 07D41C8BCE916EA3E0539014190A7DA0
수정된 행동은 그들의 행동과 아무 상관이 없는 것처럼 보입니다.else
원본 스크립트를 가져와서 동일한 세션에서 두 번만 실행하면 첫 번째에는 잘못 작동하고 두 번째에는 올바르게 작동합니다.
@hol이 관찰한 바와 같이, 이 버그는 코드가 함수 또는 저장 프로시저에 있는 경우에도 사라집니다.저의 경우 익명 블록 전체를 프로시저로 변경한 후 프로시저를 실행하여 버그가 발생하지 않았습니다.
언급URL : https://stackoverflow.com/questions/26931856/is-this-a-pl-sql-bug
'programing' 카테고리의 다른 글
텍스트 보기에 맞게 텍스트 글꼴 크기를 조정하는 방법 (0) | 2023.08.29 |
---|---|
Node.js에 있는 파일 간에 변수를 공유하시겠습니까? (0) | 2023.08.29 |
olingo v2에서 BLOB와 CLOB를 어떻게 처리합니까? (0) | 2023.08.29 |
ValueError: numpy.ndarray 크기가 변경되었습니다. 이진 비호환성을 나타낼 수 있습니다.C 헤더에서 88이 필요하고 PyObject에서 80이 필요합니다. (0) | 2023.08.29 |
ASP를 사용하는 JSONP.NET 웹 API (0) | 2023.08.29 |