हम पीएल/एसक्यूएल के किसी भी रूप में डीडीएल को मूल रूप से निष्पादित नहीं कर सकते हैं। ट्रिगर्स सहित। ऐसा करने के लिए हमें गतिशील SQL का उपयोग करने की आवश्यकता है।
ट्रिगर में एक अतिरिक्त शिकन होती है:उन्हें लेन-देन के हिस्से के रूप में निकाल दिया जाता है, और उनकी एक सीमा होती है जो हमें उनके शरीर के अंदर एक प्रतिबद्धता जारी करने से रोकती है। ओरेकल में, कोई भी डीडीएल कमांड दो कमिट जारी करता है, एक डीडीएल स्टेटमेंट के निष्पादित होने से पहले और एक के बाद। इसलिए, डीडीएल को एक ट्रिगर में निष्पादित करने के लिए हमें autonomous_transaction pragma
का उपयोग करना चाहिए , जिसका अर्थ है कि डीडीएल एक अलग, नेस्टेड लेनदेन में चलता है।
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;
स्वायत्त लेनदेन उन निर्माणों में से एक है जो हमारे लिए अपने स्वयं के अनुप्रयोगों का दुरुपयोग और तोड़फोड़ करना आसान है। आपके परिदृश्य में रोड़ा यह है कि क्रिएट रोल अपने ट्रांजेक्शन बबल में सफल हो सकता है जबकि INSETT TestTable
में विफल रहता है; ऐसा "स्वायत्त लेनदेन" का अर्थ है। तो आपको अभी भी "[आपकी] तालिका और ऑरैकल भूमिकाओं के बीच समन्वय" की गारंटी नहीं है।
एक बेहतर उपाय यह होगा कि डीएमएल को कुछ ऐसा करने के लिए छल करने की कोशिश करने के बजाय दोनों बयानों को एक प्रक्रियात्मक कॉल में लपेट दिया जाए।
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;