【问题标题】:Grant permission to trigger from owner account授予从所有者帐户触发的权限
【发布时间】:2020-08-14 13:12:04
【问题描述】:

我的两个 oracle 帐户中有一个触发器 STUDENT_DATA_UPDATE。一个是所有者帐户,另一个是用户帐户。以下是详细信息。

拥有所有权限的所有者帐户:

<connection-url>jdbc:oracle:thin:@eu.national.com:15001/STUD</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>NATIONAL_OWN</user-name>
<password>********</password>

没有权限的USER帐号:

<connection-url>jdbc:oracle:thin:@eu.national.com:15001/STUD</connection-url>
<driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
<user-name>NATIONAL_USR</user-name>
<password>********</password>

我可以从拥有权限的 OWNER 帐户更改、禁用或启用触发器。但我无法从 USER 帐户对触发器进行任何更改。我的问题是,我想授予将触发器从 NATIONAL_OWN 更改为 NATIONAL_USR 帐户的权限,该帐户可以在其中禁用和启用相同的触发器。

【问题讨论】:

  • 您需要强大的ANY 权限才能授予用户。或者在所有者模式中有一个包装程序来进行修改,但这可能只对启用/禁用才真正可行。你为什么要除所有者之外的任何人更改触发器?
  • 实际上我们在 ET 和 Prod 环境中使用 NATIONAL_USR 用户。我们有一个要求,我需要仅对特定功能禁用触发器,然后在功能执行后启用它。因此,我们无权对现有用户执行此操作。我们需要授予更改触发器的权限。我不认为给用户任何特权是正确的选择。您能否解释一下如何执行启用/禁用特定表的触发器的包装程序。
  • 包装过程是触发器所有者拥有的过程。它以所有者的权限执行。然后你将程序上的 EXECUTE 授予需要执行它的人。

标签: oracle database-administration privileges


【解决方案1】:

只有被授予强大的alter any trigger 权限的用户才能启用或禁用另一个用户的触发器,这可能是矫枉过正和危险的。您可以使用 DDL 触发器对其进行限制,但这会变得更加复杂。

您可以创建包装程序,可能在一个包中,例如在NATIONAL_OWN 架构中:

create package trigger_pkg as
  procedure disable_trigger;
  procedure enable_trigger;
end trigger_pkg;
/

create package body trigger_pkg as
  procedure disable_trigger is
  begin
    execute immediate 'alter trigger STUDENT_DATA_UPDATE disable';
  end disable_trigger;

  procedure enable_trigger is
  begin
    execute immediate 'alter trigger STUDENT_DATA_UPDATE enable';
  end enable_trigger;
end trigger_pkg;
/

grant execute on trigger_pkg to NATIONAL_USR;

那么NATIONAL_USR你可以这样做:

begin
    NATIONAL_OWN.trigger_pkg.disable_trigger;
end;
/

begin
    NATIONAL_OWN.trigger_pkg.enable_trigger;
end;
/

您可以有一个带有启用/禁用标志的过程,而不是您喜欢的。

有没有一种方法可以让我从 java 代码中真正调用这些过程 disable_trigger 和 enable_trigger。

您可以使用 CallableStatement,或者使用匿名块语法:

stmt = conn.prepareCall("begin NATIONAL_OWN.trigger_pkg.disable_trigger; end;");
stmt.execute();

或 ANSI 语法:

stmt = conn.prepareCall("{ call NATIONAL_OWN.trigger_pkg.disable_trigger }");
stmt.execute();

【讨论】:

  • 感谢您的解决方案,但我需要为我的 java 代码中的一项特定功能禁用和启用触发器。有没有一种方法可以让我真正从 java 代码中调用这些过程 disable_trigger 和 enable_trigger。
  • 当然,只需对匿名块使用 CallableStatement(不带/)。
  • 感谢 Alex 提供的解决方案。我会试一试,然后在这里告诉你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-22
  • 1970-01-01
  • 2020-11-29
  • 2019-09-20
  • 2019-03-15
  • 2015-12-06
  • 1970-01-01
相关资源
最近更新 更多