Oracle初始化具有非null约束的集合元素

时间:2019-04-04 14:16:08

标签: oracle plsql

集合(Table / Varray)中NOT NULL元素的初始化值是什么?看起来像NULL,但不是NULL。在 Oracle LIVE SQL(Oracle Database 19c企业版-19.2.0.0.0)中进行了测试

declare 
    type TArrNotNull IS table of number NOT NULL;
    type TArrAllowNull IS table of number;
    arrNotNull TArrNotNull := TArrNotNull();
    arrAllowNull TArrAllowNull := TArrAllowNull();
begin
    -- NOT NULL ARRAY ELEMENTS
    DBMS_OUTPUT.PUT_LINE('======== table/Array of number NOT NULL example ==========');    
    arrNotNull.Extend;
    IF arrNotNull(1) is null then
       DBMS_OUTPUT.PUT_LINE('NULL !!!');
    else
       DBMS_OUTPUT.PUT_LINE('NOT NULL BUT WHAT ???->['||COALESCE(arrNotNull(1),100)||']'); 
       DBMS_OUTPUT.PUT_LINE('NOT NULL BUT WHAT + 1 BECOMES NULL (LIKE REAL NULL)???->['||COALESCE(arrNotNull(1)+1,100)||']');
    end if ;

    DBMS_OUTPUT.PUT_LINE('======== table/Array of number example ==========');

    -- NOT NULL ARRAY ELEMENTS
    arrAllowNull.Extend;
    IF arrAllowNull(1) is null then
       DBMS_OUTPUT.PUT_LINE('OK IS NULL !!!');
    else
       DBMS_OUTPUT.PUT_LINE('NOT NULL !!!');
    end if ;
end;

结果:

Statement processed.
======== table/Array of number NOT NUMBER example ==========
NOT NULL BUT WHAT ???->[]
NOT NULL BUT WHAT + 1 BECOMES NULL (LIKE REAL NULL)???->[100]
======== table/Array of number example ==========
OK IS NULL !!!

UPD::如果将值分配给NUMBER变量,也是如此。

tst:=arrNotNull(1);
if tst is null then
   DBMS_OUTPUT.PUT_LINE('N NULL !!!');
else 
   DBMS_OUTPUT.PUT_LINE('N NOT NULL !!!+++'); 
end if; 

if (tst+1) is null then
   DBMS_OUTPUT.PUT_LINE('N+1 NULL !!!+++');
else 
   DBMS_OUTPUT.PUT_LINE('N+1 NOT NULL !!!+++'); 
end if; 

结果:

N NOT NULL !!!+++
N+1 NULL !!!+++

1 个答案:

答案 0 :(得分:1)

非常有趣。找不到18+的“值”,但是在12c中,您得到了NULL

我确实缩小了您的代码:

declare 
    type TArrNotNull IS table of varchar2(100) NOT NULL;
    arrNotNull TArrNotNull := TArrNotNull(1, 2, 3);
begin
    begin
        arrNotNull(2) := to_number(NULL); -- will throw, because null is not allowed
        dbms_output.put_line('arrNotNull(2) is null now');
    exception
        WHEN others THEN
            dbms_output.put_line('arrNotNull(2) couldn''t be set to null');
    end;

    arrNotNull.Extend;
    dbms_output.put_line('arrNotNull(4): >>>' || nvl(arrNotNull(4), 'NULL') || '<<<'); 
end;

结果为12分:

arrNotNull(2) couldn't be set to null
arrNotNull(4): >>>NULL<<<

获得18分(与您相同):

arrNotNull(2) couldn't be set to null
arrNotNull(4): >>><<<

另一个有趣的是,在可为空的Table of上的扩展将NULL作为默认值:

declare 
    type TArrNotNull IS table of varchar2(100);
    arrNotNull TArrNotNull := TArrNotNull(1, 2, 3);
begin

    arrNotNull.Extend;
    dbms_output.put_line('arrNotNull(4): >>>' || nvl(arrNotNull(4), 'NULL') || '<<<');
end;

所有版本的结果:

arrNotNull(4): >>>NULL<<<