Masz tylko create view
przyznane bezpośrednio Twojemu użytkownikowi. Inne uprawnienia systemowe, które możesz zobaczyć, pochodzą z roli, a role są wyłączone w procedurach składowanych z uprawnieniami osoby definiującej
. Zajrzyj do user_role_privs
aby zobaczyć, kiedy role zostały Ci przyznane, i możesz zobaczyć, jakie uprawnienia daje Ci każda rola w role_sys_privs
(z nazwą roli jako grantobiorca). Może być też kilka warstw ról.
Zobaczyłbyś ten sam błąd, gdybyś set role none
przed próbą statycznego utworzenia tabeli. Demo z minimalną konfiguracją:
create role myrole;
grant create session, create table, create procedure to myrole;
create user myuser identified by mypasswd;
grant myrole to myuser;
grant create view, unlimited tablespace to myuser;
Następnie jako ten użytkownik:
SQL> connect myuser/mypasswd
Connected.
SQL> select * from user_sys_privs;
USERNAME PRIVILEGE ADM
------------------------------ ---------------------------------------- ---
MYUSER UNLIMITED TABLESPACE NO
MYUSER CREATE VIEW NO
2 rows selected.
SQL> select * from session_privs;
PRIVILEGE
----------------------------------------
CREATE SESSION
UNLIMITED TABLESPACE
CREATE TABLE
CREATE VIEW
CREATE PROCEDURE
5 rows selected.
SQL> Create table Dummy99_99 (Dummy_Field number);
Table created.
SQL> drop table Dummy99_99 purge;
Table dropped.
SQL> set role none;
Role set.
SQL> Create table Dummy99_99 (Dummy_Field number);
Create table Dummy99_99 (Dummy_Field number)
*
ERROR at line 1:
ORA-01031: insufficient privileges
A z wersją procedury składowanej:
SQL> connect myuser/mypasswd
Connected.
SQL> create or replace procedure sp_dummy
2 as
3 begin
4 execute immediate 'Create table Dummy99_99 (Dummy_Field number)';
5 end sp_dummy;
6 /
Procedure created.
SQL> exec sp_dummy;
BEGIN sp_dummy; END;
*
ERROR at line 1:
ORA-01031: insufficient privileges
ORA-06512: at "MYUSER.SP_DUMMY", line 4
ORA-06512: at line 1
Aby móc dynamicznie tworzyć tabelę z procedury składowanej, administrator DBA będzie musiał przyznać opcję create table
bezpośrednio do użytkownika:
grant create table to myuser;
Następnie spróbuj ponownie wykonać procedurę:
SQL> connect myuser/mypasswd
Connected.
SQL> select * from user_sys_privs;
USERNAME PRIVILEGE ADM
------------------------------ ---------------------------------------- ---
MYUSER UNLIMITED TABLESPACE NO
MYUSER CREATE TABLE NO
MYUSER CREATE VIEW NO
SQL> exec sp_dummy;
PL/SQL procedure successfully completed.
SQL> desc Dummy99_99
Name Null? Type
----------------------------------------- -------- ----------------------------
DUMMY_FIELD NUMBER
Zauważ, że user_sys_privs
teraz pokazuje, że create table
zostało przyznane bezpośrednio, czego wcześniej nie było, lub w pytaniu.
Jednak jest bardzo mało prawdopodobne, abyś kiedykolwiek naprawdę chciał tworzyć obiekty dynamicznie, ponieważ schemat powinien być dobrze zdefiniowany i stabilny - zmiany tego typu powinny być kontrolowane i stanowić część procesu wydania. Ale jako ćwiczenie potrzebujesz bezpośredniego grantu.