Oracle инициализация элементов коллекции с ненулевым ограничением - PullRequest
2 голосов
/ 04 апреля 2019

Каково значение инициализации для элемента NOT NULL в коллекции (таблица / переменная)?Это похоже на NULL, но это не NULL.Протестировано в Oracle LIVE SQL (Oracle Database 19c Enterprise Edition - 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 Ответ

1 голос
/ 05 апреля 2019

Очень интересно. Не найдено «значение» для 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;

Результат в 12c:

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<<<
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...