1

我尝试创建一个触发器,该触发器自动授予对特定模式的所有新表的选择,只要在此模式中创建一个新表。

这方面的背景是 IBM InfoSphere Information Server 的异常数据库。该工具为 DataStage Jobs 中创建的异常创建新表,我希望一组开发人员能够查询这些表,而无需授予架构所有者的权限。

所以我的想法是创建一个这样的触发器:

create or replace trigger set_permissions
 after create on schema
 DECLARE
 obj_name VARCHAR2(30) := DICTIONARY_OBJ_NAME;
 BEGIN
  IF DICTIONARY_OBJ_TYPE = 'TABLE'
  THEN
   GRANT SELECT ON c##ESDB_USER.obj_name TO c##DATASTAGE_USER;
  END IF;
 END set_permissions;

但编译触发器后出现错误“PLS-00103”。它说,“GRANT”不是预期的,而是期望以下之一:

( begin case declare exit for goto if loop mod null pragma    raise return select update while with <an identifier>    <a double-quoted delimited-identifier> <a bind variable> <<    continue close current delete fetch lock insert open rollback    savepoint set sql execute commit forall merge pipe purge    json_exists json_value json_query json_object json_array

在我看来,触发器内不允许使用 GRANT。如果是这样,是否有另一种方法可以自动授予用户对特定架构内新表的选择权限?

4

1 回答 1

3

你得到的错误说你不能像那样执行 DDL(是的,grant是一个 DDL) - 它必须作为动态 SQL 完成,使用execute immediate.

但是,在这种情况下它无济于事,因为 DDL 隐式提交,并且您不能在触发器内提交。

现在你会说你可以创建一个触发器作为一个自治事务嗯,是的 - 你可以,但在这种情况下它不会有帮助,因为该表尚未创建(即它还不存在)。


这是一种解决方法;看看它是否有帮助。简单来说:

  • 创建一个辅助程序(使其更简单),它实际上将执行grant操作
  • 让触发器提交一个将调用该过程的作业

方法如下:我以 Scott 的身份连接并将授予用户 Mike 权限(因为我没有您的用户):

SQL> show user
USER is "SCOTT"
SQL>
SQL> -- Auxiliary procedure
SQL> create or replace procedure p_grant (par_str in varchar2) is
  2  begin
  3    execute immediate par_str;
  4  end;
  5  /

Procedure created.

SQL> -- Trigger
SQL> create or replace trigger set_permissions
  2    after create on schema
  3  declare
  4    l_job    number;
  5    l_str    varchar2(200);
  6    obj_name varchar2(30) := dictionary_obj_name;
  7  begin
  8    if dictionary_obj_type = 'TABLE'
  9    then
 10      l_str := 'GRANT SELECT ON ' ||obj_name || ' TO mike';
 11      dbms_job.submit
 12        (l_job,
 13         'begin p_grant(' || chr(39) || l_str || chr(39) ||'); end;',
 14          sysdate
 15        );
 16    end if;
 17  end set_permissions;
 18  /

Trigger created.

SQL>

测试:

SQL> create table test (id number);

Table created.

SQL> insert into test values (222);

1 row created.

SQL> commit;

Commit complete.

以 Mike 的身份连接并检查它看到的内容:

SQL> connect mike/lion
Connected.
SQL> select * from scott.test;

        ID
----------
       222

SQL>
于 2019-09-22T13:55:53.960 回答