Kami tidak dapat menjalankan DDL secara native dalam bentuk PL/SQL apa pun. termasuk pemicu. Untuk melakukan itu kita perlu menggunakan SQL dinamis.
Pemicu memiliki kerutan tambahan:mereka dipecat sebagai bagian dari transaksi, dan mereka memiliki batasan yang melarang kami mengeluarkan komit di dalam tubuh mereka. Di Oracle, setiap perintah DDL mengeluarkan dua komit, satu sebelum dan satu setelah pernyataan DDL dijalankan. Jadi, untuk mengeksekusi DDL di pemicu kita harus menggunakan autonomous_transaction pragma
, yang berarti DDL berjalan dalam transaksi bertingkat yang terpisah.
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;
Transaksi otonom adalah salah satu konstruksi yang mudah bagi kita untuk menyalahgunakan dan menyabot aplikasi kita sendiri. Dalam skenario Anda, hambatannya adalah CREATE ROLE dapat berhasil dalam gelembung transaksinya sementara INSERTT ke TestTable
gagal; itulah arti dari "transaksi otonom". Jadi Anda masih belum dijamin "koherensi antara tabel [Anda] dan peran oracle satu".
Solusi yang lebih baik adalah dengan menggabungkan kedua pernyataan ke dalam panggilan prosedural, daripada mencoba mengelabui DML agar melakukan sesuatu yang tidak seharusnya dilakukan.
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;