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

Czy mogę wyłączyć spust wewnątrz spustu w Oracle?

Tak zrozumiałem pytanie. Sprawdź, czy to pomoże.

Przykładowe tabele:

SQL> create table test (id number);

Table created.

SQL> create table test_2 (id number);

Table created.

Wyzwalacz na test_2 co zapobiega wstawkom:

SQL> create or replace trigger trg2
  2    before insert or update on test_2
  3    for each row
  4  begin
  5    raise_application_error(-20000, 'Not allowed');
  6  end;
  7  /

Trigger created.

Czy to działa?

SQL> insert into test_2 (id) values (1);
insert into test_2 (id) values (1)
            *
ERROR at line 1:
ORA-20000: Not allowed
ORA-06512: at "SCOTT.TRG2", line 2
ORA-04088: error during execution of trigger 'SCOTT.TRG2'

Tak, to działa.

Teraz wyzwalacz test co ma a) wyłączyć trg2 wyzwalacz i b) wstaw wartość do test_2 . Prosty kod byłby wtedy

SQL> create or replace trigger trg1
  2    before insert on test
  3    for each row
  4  begin
  5    execute immediate 'alter trigger trg2 disable';
  6    insert into test_2 (id) values (:new.id);
  7  end;
  8  /

Trigger created.

Przetestujmy to:

SQL> insert into test (id) values (1);
insert into test (id) values (1)
            *
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SCOTT.TRG1", line 2
ORA-04088: error during execution of trigger 'SCOTT.TRG1'

Aha. Nie można COMMIT w spuście. Gdzie to jest? W alter trigger dynamicznego SQL - jest to DDL i niejawnie zatwierdza. Jak to naprawić? Uczyń z niej (wyzwalacz) autonomiczną transakcję:

SQL> create or replace trigger trg1
  2    before insert on test
  3    for each row
  4  declare
  5    pragma autonomous_transaction;
  6  begin
  7    execute immediate 'alter trigger trg2 disable';
  8    insert into test_2 (id) values (:new.id);
  9  end;
 10  /

Trigger created.

SQL> insert into test (id) values (1);
insert into test (id) values (1)
            *
ERROR at line 1:
ORA-06519: active autonomous transaction detected and rolled back
ORA-06512: at "SCOTT.TRG1", line 6
ORA-04088: error during execution of trigger 'SCOTT.TRG1'

To kolejny błąd; mówi, że - jeśli mamy autonomiczną transakcję - musimy zatwierdzić lub wycofać. Zatwierdźmy (ponieważ prawdopodobnie to właśnie chciałbyś zrobić):

SQL> create or replace trigger trg1
  2    before insert on test
  3    for each row
  4  declare
  5    pragma autonomous_transaction;
  6  begin
  7    execute immediate 'alter trigger trg2 disable';
  8    insert into test_2 (id) values (:new.id);
  9    commit;
 10  end;
 11  /

Trigger created.

SQL> insert into test (id) values (100);

1 row created.

SQL> select * From test;

        ID
----------
       100

SQL> select * from test_2;

        ID
----------
       100

SQL>

Prawidłowy; teraz działa .

Proponuję ponownie przeczytać komentarze zamieszczone pod Twoim pytaniem, zobaczyć ten przykład i wybrać, co zrobić.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pobieranie danych z tabeli za pomocą PL/SQL

  2. Utworzenie pliku .jks z pliku .crt i .key jest możliwe

  3. jak zadeklarować SQLCA.SQLERRD?

  4. liczba Oracle null na kolumny

  5. Różnica między count(1) i count(*) w Oracle