在触发器 Oracle 11 中创建语句
Create Statement in a Trigger Oracle 11
对于 Oracle 11g 和 RDMBS(一般而言)仍然很新
我想添加一个触发器,当一行被插入 table 时创建一个用户。
我遇到默认错误,说我不能在触发器的 body 中放置创建语句 (PLS-00103)。我尝试了 body 中线的不同位置,并在触发器中完全隔离了线,但错误总是发生在 "CREATE" 位置。有谁知道这是否是对 triggers/stored 程序的限制?如果是这样,这种限制的解决方法是什么?
我可以想象有一个创建某些东西的触发器对数据库来说是极其危险的,但我没有足够的经验来确定。
编辑添加此类触发器的原因:
之所以要添加这样的触发器是因为
首先,我要初始化一个员工table。
其次,table 中没有员工,每个添加的员工将 (1) 创建一个用户名并传递给他们使用,以及 (2) 为他们提供 employee_role
编辑添加代码
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;
/
谢谢
您不能 运行 来自任何 PL/SQL 上下文的任何 DDL,包括触发器,除非您使用动态 SQL;所以 create ...
在 PL/SQL 块中作为静态 SQL 无效。
但是there are further restrictions on triggers。因为它们在 期间 DML 语句中触发,所以您不能在一个语句中提交或回滚,并且 DDL 会隐式提交。可以解决这个问题,但这不是一个好主意。
假设您确实需要在插入行的同时创建用户,那么使用过程进行插入并动态创建用户,然后确保仅通过调用过程插入行会更简单.
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;
/
您仍然需要注意,即使创建失败,插入也会被隐式提交。最好在插入之前检查用户 ID 是否为有效标识符,并且构成 create
语句一部分的任何其他传递参数也有效,以最大限度地降低风险。
对于 Oracle 11g 和 RDMBS(一般而言)仍然很新
我想添加一个触发器,当一行被插入 table 时创建一个用户。
我遇到默认错误,说我不能在触发器的 body 中放置创建语句 (PLS-00103)。我尝试了 body 中线的不同位置,并在触发器中完全隔离了线,但错误总是发生在 "CREATE" 位置。有谁知道这是否是对 triggers/stored 程序的限制?如果是这样,这种限制的解决方法是什么?
我可以想象有一个创建某些东西的触发器对数据库来说是极其危险的,但我没有足够的经验来确定。
编辑添加此类触发器的原因:
之所以要添加这样的触发器是因为
首先,我要初始化一个员工table。
其次,table 中没有员工,每个添加的员工将 (1) 创建一个用户名并传递给他们使用,以及 (2) 为他们提供 employee_role
编辑添加代码
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;
/
谢谢
您不能 运行 来自任何 PL/SQL 上下文的任何 DDL,包括触发器,除非您使用动态 SQL;所以 create ...
在 PL/SQL 块中作为静态 SQL 无效。
但是there are further restrictions on triggers。因为它们在 期间 DML 语句中触发,所以您不能在一个语句中提交或回滚,并且 DDL 会隐式提交。可以解决这个问题,但这不是一个好主意。
假设您确实需要在插入行的同时创建用户,那么使用过程进行插入并动态创建用户,然后确保仅通过调用过程插入行会更简单.
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;
/
您仍然需要注意,即使创建失败,插入也会被隐式提交。最好在插入之前检查用户 ID 是否为有效标识符,并且构成 create
语句一部分的任何其他传递参数也有效,以最大限度地降低风险。