【问题标题】:How to grant trigger access to a table如何授予对表的触发器访问权限
【发布时间】:2019-01-18 15:50:31
【问题描述】:

我收到一条关于我已成功创建的触发器的错误消息。

我试过了……

GRANT SELECT ON OTHER_TABLE TO [me];
call SYS.DBA_ASSIST.GRANT_OBJ_PERMS('dbo.MYTABLE','SELECT','dbo.OTHER_TABLE');`

这里是触发器的代码...

  CREATE OR REPLACE TRIGGER PREVENT_INVALID_ID
  BEFORE INSERT OR UPDATE ON dbo.MYTABLE
  FOR EACH ROW
  DECLARE ROW_COUNT NUMBER;
  BEGIN
  SELECT COUNT(*) INTO ROW_COUNT 
         FROM [OTHER_TABLE] WHERE OTHER_TABLE_ID = :new.MYTABLE_ID;
  IF ROW_COUNT = 0 THEN
    RAISE_APPLICATION_ERROR(-20101, 'The ID provided is invalid.');
    END IF;
  END;`

user_errors 中的错误消息是“PL/SQL: ORA-00942: table or view does not exist”

知道如何获得访问 OTHER_TABLE 的触发器吗?

我了解无法授予触发器访问/授权。但我不清楚我需要运行什么代码才能让触发器工作。

提前致谢, 乔什

【问题讨论】:

  • 如果这是针对 Oracle 的,则不能命名表 [OTHER_TABLE]。如果 OTHER_TABLE_ID 是主键或唯一索引,为什么不在表 dbo.MYTABLE 上使用外键?
  • 同意。执行此规则的标准方式(有效且唯一安全的方式)是使用外键约束。使用触发器是一种糟糕的做法。

标签: oracle plsql triggers sql-grant


【解决方案1】:

如果MYTABLEOTHER_TABLE属于同一个用户,则不需要特权:

SQL> show user
USER is "SCOTT"
SQL> create table other_table (other_Table_id number);

Table created.

SQL> create table mytable (mytable_id number);

Table created.

SQL> create or replace trigger prevent_invalid_id
  2    before insert or update on mytable
  3    for each row
  4  declare
  5    row_count number;
  6  begin
  7    select count(*) into row_count
  8    from other_table where other_table_id = :new.mytable_id;
  9
 10    if row_count = 0 then
 11       raise_application_error(-20101, 'The ID provided is invalid');
 12    end if;
 13  end;
 14  /

Trigger created.

SQL>

但是,如果它们属于不同的用户,那么OTHER_TABLE 的所有者必须将SELECT 权限授予。不过,这还不够——您必须在 OTHER_TABLE 之前加上它的所有者名称(例如 other_user.other_table),或者在我自己的架构中创建一个同义词,指向其他用户的 OTHER_TABLE。例如:

SQL> drop table other_table;

Table dropped.

SQL> connect mike/lion@xe
Connected.
SQL> create table other_table (other_Table_id number);

Table created.

SQL> grant select on other_table to scott;

Grant succeeded.

SQL> connect scott/tiger@xe
Connected.
SQL> create or replace trigger prevent_invalid_id
  2    before insert or update on mytable
  3    for each row
  4  declare
  5    row_count number;
  6  begin
  7    select count(*) into row_count
  8    from MIKE.other_table where other_table_id = :new.mytable_id;
  9
 10    if row_count = 0 then
 11       raise_application_error(-20101, 'The ID provided is invalid');
 12    end if;
 13  end;
 14  /

Trigger created.

SQL>

注意第 8 行:MIKE.other_table

只是为了说明如果您省略/删除所有者的姓名会发生什么:

SQL> l8
  8*   from MIKE.other_table where other_table_id = :new.mytable_id;
SQL> c/mike.//
  8*   from other_table where other_table_id = :new.mytable_id;
SQL> l
  1  create or replace trigger prevent_invalid_id
  2    before insert or update on mytable
  3    for each row
  4  declare
  5    row_count number;
  6  begin
  7    select count(*) into row_count
  8    from other_table where other_table_id = :new.mytable_id;
  9
 10    if row_count = 0 then
 11       raise_application_error(-20101, 'The ID provided is invalid');
 12    end if;
 13* end;
SQL> /

Warning: Trigger created with compilation errors.

SQL> show err
Errors for TRIGGER PREVENT_INVALID_ID:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/3      PL/SQL: SQL Statement ignored
5/8      PL/SQL: ORA-00942: table or view does not exist
SQL>

看到了吗? ORA-00942。

【讨论】:

    【解决方案2】:

    想通了:GRANT SELECT ON OTHER_TABLE TO dbo

    让我失望的是,当我在寻找有关如何执行此操作的说明时,使用了“表所有者”这个词。我以为我是桌子的主人。相反,需要特权的是架构 (dbo)。

    【讨论】:

      猜你喜欢
      • 2018-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 2019-06-10
      相关资源
      最近更新 更多