subirc
asked on
Perform execute immediate within a trigger
Can I do excute an sql dynamically within a trigger. I have an execute immediate statement as given below:
CREATE OR REPLACE TRIGGER MYTRIGGER
AFTER DELETE OR INSERT OR UPDATE
ON MYTABLE
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
v_SQL VARCHAR2(15000);
BEGIN
v_SQL := myPkg.getViewSQL;
EXECUTE IMMEDIATE v_SQL;
END MYTRIGGER
/
All I am doing is getting a sql (which is a create or replace view statement) and trying to execute it within the trigger.
I am getting an error
ORA-00936: missing expression
ORA-06512: at "MY_SCHEMA.MY_TRIGGER", line 5
ORA-04088: error during execution of trigger "MY_SCHEMA.MY_TRIGGER"
Any help is appreciated
CREATE OR REPLACE TRIGGER MYTRIGGER
AFTER DELETE OR INSERT OR UPDATE
ON MYTABLE
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
v_SQL VARCHAR2(15000);
BEGIN
v_SQL := myPkg.getViewSQL;
EXECUTE IMMEDIATE v_SQL;
END MYTRIGGER
/
All I am doing is getting a sql (which is a create or replace view statement) and trying to execute it within the trigger.
I am getting an error
ORA-00936: missing expression
ORA-06512: at "MY_SCHEMA.MY_TRIGGER", line 5
ORA-04088: error during execution of trigger "MY_SCHEMA.MY_TRIGGER"
Any help is appreciated
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
It's not a DDL, its a DML. Correct me if I am wrong. Create or replace view is DML, and DDLs are when you create a table/index.constaint etc.
However, I did add the pragma autonomous transaction to the trigger and still getting the same error, and myPkg.getViewSQL returns a valid view; which if I call outside the trigger runs and compiles
subirc
However, I did add the pragma autonomous transaction to the trigger and still getting the same error, and myPkg.getViewSQL returns a valid view; which if I call outside the trigger runs and compiles
subirc
>Create or replace view is DML
wrong. CREATE, ALTER, DROP, TRUNCATE are all DDL statements.
wrong. CREATE, ALTER, DROP, TRUNCATE are all DDL statements.
ASKER
Jankovsky,
You are right in both of your points. I need the PRAGMA AUTONOMOUS TRANSACTION and my getViewsql was not returning two view DDLs i.e. I had two CREATE OR REPLACE VIEW statements returned from the myPkg.getViewSQL function. Now, I have two functions myPkg.getViewSQL1 and myPkg.getviewSQL2 and now they run fine.
So, I tried this script and it works now
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ------
declare
myresult VARCHAR2(30000);
begin
myresult := myPkg.getViewSQL1;
execute immediate myresult;
myresult := myPkg.getViewSQL2;
execute immediate myresult;
end;
/
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -----
Now, putting this in the trigger though, I am running into permissions problem. Looks like I don't have permission to execute the DDL from a trigger something which I don't have control on. So I decided to write a job instead using DMBS_JOB package. How do I write a job that runs everytime the table is inserted/updated/deleted? Or, I cannot do that and have to run the job every two minutes.
Also, how do I go about doing it ? I don't have much experience with DBMS_JOB package.
Will this work ?
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
(
job => X,
what => ' declare
myresult VARCHAR2(30000);
begin
myresult := myPkg.getViewSQL1;
execute immediate myresult;
myresult := myPkg.getViewSQL2;
execute immediate myresult;
end; ' ,
next_date => to_date('23/10/2008 09:34:44','dd/mm/yyyy hh24:mi:ss'),
interval => 'SYSDATE+1/3600',
no_parse => FALSE,
);
END;
-------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- -
Jankovsky, thank you, you already earned the initial points, I am raising the points now.
subirc
You are right in both of your points. I need the PRAGMA AUTONOMOUS TRANSACTION and my getViewsql was not returning two view DDLs i.e. I had two CREATE OR REPLACE VIEW statements returned from the myPkg.getViewSQL function. Now, I have two functions myPkg.getViewSQL1 and myPkg.getviewSQL2 and now they run fine.
So, I tried this script and it works now
--------------------------
declare
myresult VARCHAR2(30000);
begin
myresult := myPkg.getViewSQL1;
execute immediate myresult;
myresult := myPkg.getViewSQL2;
execute immediate myresult;
end;
/
--------------------------
Now, putting this in the trigger though, I am running into permissions problem. Looks like I don't have permission to execute the DDL from a trigger something which I don't have control on. So I decided to write a job instead using DMBS_JOB package. How do I write a job that runs everytime the table is inserted/updated/deleted? Or, I cannot do that and have to run the job every two minutes.
Also, how do I go about doing it ? I don't have much experience with DBMS_JOB package.
Will this work ?
--------------------------
DECLARE
X NUMBER;
BEGIN
SYS.DBMS_JOB.SUBMIT
(
job => X,
what => ' declare
myresult VARCHAR2(30000);
begin
myresult := myPkg.getViewSQL1;
execute immediate myresult;
myresult := myPkg.getViewSQL2;
execute immediate myresult;
end; ' ,
next_date => to_date('23/10/2008 09:34:44','dd/mm/yyyy hh24:mi:ss'),
interval => 'SYSDATE+1/3600',
no_parse => FALSE,
);
END;
--------------------------
Jankovsky, thank you, you already earned the initial points, I am raising the points now.
subirc
ASKER
Sorry increasing the points
ASKER
I will put up a new thread since I asked a new question
ASKER
I will be posting a new thread as I changed the question.
And the reason DDL is not allowed within a trigger (Jankovsky's #1) without the suggested pragma is that DDL has an implied COMMIT (both before and after the execution of the provided statement), which is not allowed within a trigger.