Skip to content

Вложенные и именованные блоки

В прошлый раз был рассмотрен самый простой вариант блоков в PL/SQL - анонимные блоки.

В этой части мы рассмотрим возможность вкладывать блоки внутрь других блоков, а также давать блокам имена.

Вложенные блоки

plsql
declare
    l_a number := 10;
begin
    -- Начало вложенного блока
    declare
        l_b number;
    begin
        l_b := 20;
        dbms_output.put_line(l_a);
        dbms_output.put_line(l_b);
    end;
end;
/
declare
    l_a number := 10;
begin
    -- Начало вложенного блока
    declare
        l_b number;
    begin
        l_b := 20;
        dbms_output.put_line(l_a);
        dbms_output.put_line(l_b);
    end;
end;
/

Вложенные блоки могут обращаться ко всем объектам, которые были объявлены во внешних блоках. Именно поэтому в примере выше мы свободно можем обращаться из к переменной l_a, которая была объявлена во внешнем блоке.

Обратное неверно - мы не можем обращаться из внешнего блока к объектам, которые были объявлены во внутреннем блоке:

plsql
declare
    l_a number := 10;
begin
    declare
        l_b number;
    begin
        l_b := 20;
        dbms_output.put_line(l_b);
        dbms_output.put_line(l_a);
    end;

    -- Мы не можем обращаться к переменной l_b
    if l_b = 10 then
        dbms_output.put_line('l_b равно 10')
    else
        dbms_output.put_line('l_b не равно 10');
    end if;
end;
/
declare
    l_a number := 10;
begin
    declare
        l_b number;
    begin
        l_b := 20;
        dbms_output.put_line(l_b);
        dbms_output.put_line(l_a);
    end;

    -- Мы не можем обращаться к переменной l_b
    if l_b = 10 then
        dbms_output.put_line('l_b равно 10')
    else
        dbms_output.put_line('l_b не равно 10');
    end if;
end;
/

Метки блоков

Мы можем именовать блоки метками, чтобы можно было отличить несколько объектов с одним и тем же именем во внешних блоках:

plsql
<<main>>
declare
    l_a number := 10;
begin
    <<child>>
    declare
        l_a number := 20;
    begin
        dbms_output.put_line(main.l_a);
        dbms_output.put_line(child.l_a);
    end;
end;
/
<<main>>
declare
    l_a number := 10;
begin
    <<child>>
    declare
        l_a number := 20;
    begin
        dbms_output.put_line(main.l_a);
        dbms_output.put_line(child.l_a);
    end;
end;
/

В примере выше во внешнем и внутреннем блоках объявлены переменные l_a, и используя метки блоков <<main>> и <<child>>, мы можем указывать, какую же именно переменную использовать - из внешнего, либо из внутреннего блока.

WARNING

По возможности, подобных случаев следует избегать, так как они усложняют чтение программы.