Блок анонимного кода с DDL работает, но при создании как процедура получить ошибку прав - PullRequest
0 голосов
/ 06 января 2020

В нашей базе данных Oracle 12 c я пытаюсь создать пакет, который будет отбрасывать и при необходимости создавать таблицы.

Для первого теста я написал блок анонимного кода, и он работает хорошо:

begin
    begin
        execute immediate 'Drop Table my_table';
        exception
           when OTHERS then
                if sqlcode = -942 then
                    null;
                end if;
    end;
    begin
        execute immediate 'Create Table my_table as
        WITH 
        sub_qy AS(
        SELECT DISTINCT
            ...
        )
        SELECT * FROM sub_qy';
    end;
    execute immediate 'GRANT SELECT ON my_table to my_role';

Затем я попытался создать пакет и поместить блок анонимного кода в процедуру, но при выполнении процедуры я получаю сообщение об ошибке:

ORA-01031: insufficient privileges

Вот лог c:

create package my_refresh_pkg as
    procedure create_first_table;
end my_refresh_pkg;

create package body my_refresh_pkg as
    procedure create_first_table is
    begin
        begin
            execute immediate 'Drop Table my_table';
            exception
               when OTHERS then
                    if sqlcode = -942 then
                        null;
                    end if;
        end;
        begin
            execute immediate 'Create Table my_table as
            WITH 
            sub_qy AS(
            SELECT DISTINCT
                ...
            )
            SELECT * FROM sub_qy';
        end;
        execute immediate 'GRANT SELECT ON my_table to my_role';
    end create_first_table;
end my_refresh_pkg;

Я создал пакет в своей собственной схеме, поэтому я не уверен, почему я получаю эту ошибку. Любое понимание будет оценено.

1 Ответ

0 голосов
/ 06 января 2020

Подозрительная часть такова:

SELECT DISTINCT
       ...

, так как пахнет , как известная проблема с привилегиями. Если таблицы, которые вы использовали в предложении FROM вышеприведенного утверждения, принадлежат не вам, а кому-то другому, и вы приобрели select (или любые другие) привилегии через роль , что ж, выиграл не работает в именованных процедурах PL / SQL. Да, это хранимая процедура, или функция, или - package, которую вы написали.

Решение заключается в предоставлении этих привилегий непосредственно вам, а не через роль.


[РЕДАКТИРОВАТЬ: запуск вашего кода в моей базе данных - без ошибок]

SQL> create or replace package my_refresh_pkg as
  2      procedure create_first_table;
  3  end my_refresh_pkg;
  4  /

Package created.

SQL> create or replace package body my_refresh_pkg as
  2      procedure create_first_table is
  3      begin
  4          begin
  5              execute immediate 'Drop Table my_table';
  6              exception
  7                 when OTHERS then
  8                      if sqlcode = -942 then
  9                          null;
 10                      end if;
 11          end;
 12          begin
 13              execute immediate 'Create Table my_table as
 14              WITH
 15              sub_qy AS(
 16              SELECT DISTINCT
 17                  job from emp
 18              )
 19              SELECT * FROM sub_qy';
 20          end;
 21          execute immediate 'GRANT SELECT ON my_table to my_role';
 22      end create_first_table;
 23  end my_refresh_pkg;
 24  /

Package body created.

SQL> create role my_role;

Role created.

Тестирование:

SQL> exec my_refresh_pkg.create_first_table;

PL/SQL procedure successfully completed.

SQL> select * From my_table;

JOB
---------
CLERK
SALESMAN
PRESIDENT
MANAGER
ANALYST

SQL>
...