Reputation: 51
Still pretty new to Oracle 11g and RDMBS (in general)
I want to add a trigger which would create a user when a row was inserted into a table.
I encountered the default error saying that I can not put a create statement in the body of the trigger (PLS-00103). I tried different positions of the line in the body as well as isolated the line completely in a trigger but the error always occurs at the "CREATE" position. Does anyone know if this is a restriction on triggers/stored procedures? If so, what would be the workaround for this sort of restriction?
I can imagine having a trigger which creates something can be extremely dangerous to the database but I am not experienced enough to know for sure.
edit reasoning for adding such a trigger:
The reason I want to add such a trigger is because
First, I want to initialize an employee table.
Second, with no employees in the table, each added employee will (1) create a username and pass for them to use and (2) provide them the privileges of an employee_role
edit added code
CREATE VIEW EMPLOYEES_VIEW AS
SELECT * FROM EMPLOYEES_TABLE;
CREATE TRIGGER NEW_EMPLOYEE_ROLE
INSTEAD OF INSERT
ON EMPLOYEES_VIEW
DECLARE INSERTED_EMPID CHAR;
BEGIN
INSERTED_EMPID:= :NEW.EMPID;
INSERT INTO EMPLOYEES_TABLE
(EMPID, NAME, TAXID, COUNTRY, HIREDATE, BIRTHDATE, SALARY, BONUS, DEPTID, ADDRESS, ADDRESS_CITY, ADDRESS_ZIP, ADDRESS_COUNTRY)
VALUES
(:NEW.EMPID, :NEW.NAME, :NEW.TAXID, :NEW.COUNTRY, :NEW.HIREDATE, :NEW.BIRTHDATE, :NEW.SALARY, :NEW.BONUS, :NEW.DEPTID, :NEW.ADDRESS, :NEW.ADDRESS_CITY, :NEW.ADDRESS_ZIP, :NEW.ADDRESS_COUNTRY);
CREATE USER INSERTED_EMPID IDENTIFIED BY INSERTED_EMPID;
GRANT EMPLOYEE_ROLE TO INSERTED_EMPID;
END;
/
Thank you
Upvotes: 0
Views: 102
Reputation: 191580
You can't run any DDL from any PL/SQL context, which includes a trigger, unless you use dynamic SQL; so create ...
isn't valid as static SQL in a PL/SQL block.
But there are further restrictions on triggers. Because they fire during a DML statement, you can't commit or rollback from within one, and DDL implicitly commits. It's possible to get around that but it isn't a good idea.
Assuming you really need to create a user at the same time you insert a row it would be simpler to use a procedure to do the insert and dynamically create the user, and then ensure rows are only inserted by calling the procedure.
create or replace procedure add_user(p_user_id varchar2, ...) as
begin
insert into your_table ... ;
execute immediate 'create user ' || p_user_id
|| ' identified by ...';
end;
/
You still need to still be aware that the insert will be implicitly comitted even if the create fails. It would be a good idea to check the user ID is a valid identifier, and any other passed parameters that form part of the create
statement are also valid, before you insert to minimise that risk.
Upvotes: 4