【问题标题】:Oracle : Is it possible to create a Role in a Trigger?Oracle:是否可以在触发器中创建角色?
【发布时间】:2013-12-22 21:38:30
【问题描述】:

我有一个包含一些数据的单独表,我想在每次在该表中插入新行时创建一个新角色。

我创建了以下触发器:

create or replace 
TRIGGER TestTrigger
BEFORE INSERT ON TestTable
REFERENCING OLD AS OLD NEW AS NEW 

FOR EACH ROW BEGIN 
    create role :New.RoleName;
END;

但触发器无法编译。 我有错误:PLS-00103:PLS-00103:在预期以下情况之一时遇到符号“CREATE”:(begin case declare exit for goto if loop mod null pragma raise return select update while with

这可能吗?

【问题讨论】:

  • 我怀疑您不能以这种方式在触发器中使用 DDL。您可以尝试使用 Execute Immediate 来执行您的 CREATE,但我不知道是否可以像这样创建角色。
  • 您可以使用execute immediate创建角色;但不在触发器内,因为您不能在触发器内提交,而 DDL 会进行隐式提交。您可以通过使其自主或提交工作来解决这个问题,但这有点令人费解。似乎是一个奇怪的要求。如果您必须从您的应用程序创建角色,为什么不创建一个角色 - 在您的表中复制它会增加什么?
  • 我复制它们的原因是,对于每个角色,我都需要一些额外的信息:描述、创建日期、ID 等。因为我无法将这些列添加到“默认”角色表中在 Oracle 中,我创建了一个单独的表来处理附加信息。但是,我仍然需要关心我的表角色和 oracle 角色之间的一致性。
  • 嗯,即使您可以从触发器中执行此操作,我也宁愿创建一个作业来解析表并创建角色...出于安全目的。

标签: oracle plsql triggers ddl


【解决方案1】:

我们不能以任何形式的 PL/SQL 本地执行 DDL。包括触发器。为此,我们需要使用动态 SQL。

触发器有一个额外的问题:它们作为事务的一部分被触发,并且它们有一个限制,禁止我们在它们的主体内发出提交。在 Oracle 中,任何 DDL 命令都会发出两次提交,一次是在执行 DDL 语句之前,一次是在执行 DDL 语句之后。因此,要在触发器中执行 DDL,我们必须使用autonomous_transaction pragma,这意味着 DDL 在单独的嵌套事务中运行。

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;

自治事务是我们很容易误用和破坏我们自己的应用程序的结构之一。在您的场景中,问题是 CREATE ROLE 可以在其事务泡沫中成功,而 INSERTT 到 TestTable 失败;这就是“自主交易”的含义。所以你仍然不能保证“[你的]表和oracle角色之间的一致性”。

更好的解决方案是将两个语句包装到一个过程调用中,而不是试图诱使 DML 做一些它不应该做的事情。

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; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-03
    • 2013-12-24
    • 2018-02-07
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    相关资源
    最近更新 更多