Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Oracle:Czy można utworzyć rolę w wyzwalaczu?

Nie możemy natywnie wykonać DDL w jakiejkolwiek formie PL/SQL. w tym wyzwalacze. Aby to zrobić, musimy użyć dynamicznego SQL.

Wyzwalacze mają dodatkową zmarszczkę:są odpalane w ramach transakcji i mają ograniczenie, które zabrania nam wydawania commitów wewnątrz ich ciała. W Oracle każde polecenie DDL wydaje dwa zatwierdzenia, jeden przed i jeden po wykonaniu instrukcji DDL. Tak więc, aby wykonać DDL w wyzwalaczu, musimy użyć autonomous_transaction pragma , co oznacza, że ​​DDL działa w oddzielnej, zagnieżdżonej transakcji.

create or replace TRIGGER TestTrigger
    BEFORE INSERT ON TestTable
    REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 
declare
    pragma autonomous_transaction;
BEGIN 
    execute immediate 'create role '|| :New.RoleName;
END;

Transakcje autonomiczne to jedna z tych konstrukcji, które są dla nas łatwe do nadużycia i sabotowania własnych aplikacji. W twoim scenariuszu haczyk polega na tym, że funkcja CREATE ROLE może odnieść sukces w swojej bańce transakcyjnej, podczas gdy WSTAWIĆ do TestTable zawodzi; takie jest znaczenie „transakcji autonomicznej”. Więc nadal nie masz gwarancji „spójności między [twój] stołem a rolą wyroczni jeden”.

Lepszym rozwiązaniem byłoby zawinięcie obu instrukcji w wywołanie proceduralne, zamiast próbować nakłonić DML do zrobienia czegoś, czego nie powinno się robić.

create or replace procedure create_role
     ( p_role_name in user_roles.role%type
       , p_desc in testtable.description%type )
is
    pragma autonomous_transaction;
begin 
    insert into testtable
        ( id, creationdate, rolename, description) 
    values
        ( some_seq.nextval, sysdate, p_role_name, p_desc );
    execute immediate 'create role '|| p_role_name;
end; 



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wywołanie funkcji Oracle PLSQL w drugiej funkcji

  2. SQL Query do konwersji wyrażenia cron na format daty/czasu

  3. Jak połączyć wiele wierszy w jeden w Oracle bez tworzenia procedury składowanej?

  4. Łączenie 3 tabel Oracle SQL

  5. Dlaczego GETDATE() jest nieprawidłowym identyfikatorem?