Oracle数据库中表触发的多模式权限

时间:2010-04-16 22:46:35

标签: database oracle triggers oracle10g ora-00942

我正在尝试编写一个表触发器,用于查询触发器所在架构之外的另一个表。这可能吗?在我的架构中查询表似乎没有问题,但我得到:

Error: ORA-00942: table or view does not exist

尝试查询架构外的表时。

修改

我很抱歉第一次没有提供尽可能多的信息。我觉得这个问题更简单。

我正在尝试在一个表上创建一个触发器,该表根据某些数据的存在来更改新插入行上的某些字段,这些数据可能存在于另一个模式中的表中,也可能不存在。

我用来创建触发器的用户帐户确实具有独立运行查询的权限。事实上,我有触发器打印我正在尝试运行的查询,并且能够成功运行它。

我还应该注意,我正在使用EXECUTE IMMEDIATE语句动态构建查询。这是一个例子:

CREATE OR REPLACE TRIGGER MAIN_SCHEMA.EVENTS
BEFORE INSERT
ON MAIN_SCHEMA.EVENTS REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE 
    rtn_count NUMBER := 0;
    table_name VARCHAR2(17) := :NEW.SOME_FIELD;
    key_field VARCHAR2(20) := :NEW.ANOTHER_FIELD;
BEGIN
    CASE
        WHEN (key_field = 'condition_a') THEN
            EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_A.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
        WHEN (key_field = 'condition_b') THEN
            EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_B.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
        WHEN (key_field = 'condition_c') THEN
            EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_C.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
    END CASE;

    IF (rtn_count > 0) THEN
        -- change some fields that are to be inserted
    END IF; 
END;

触发器在EXECUTE IMMEDIATE上因前面提到的错误而失败。

修改

我做了更多的研究,我可以提供更多的澄清。

我用来创建此触发器的用户帐户不是MAIN_SCHEMA或OTHER_SCHEMA_X中的任何一个。我正在使用的帐户(ME)通过架构用户自己获得所涉及表的权限。例如(USER_TAB_PRIVS):

GRANTOR        GRANTEE TABLE_SCHEMA    TABLE_NAME PRIVILEGE GRANTABLE HIERARCHY
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     DELETE    NO        NO
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     INSERT    NO        NO
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     SELECT    NO        NO
MAIN_SCHEMA    ME       MAIN_SCHEMA    EVENTS     UPDATE    NO        NO
OTHER_SCHEMA_X ME       OTHER_SCHEMA_X TARGET_TBL SELECT    NO          NO

我拥有以下系统权限(USER_SYS_PRIVS):

USERNAME   PRIVILEGE            ADMIN_OPTION
ME         ALTER ANY TRIGGER    NO
ME         CREATE ANY TRIGGER   NO
ME         UNLIMITED TABLESPACE NO

这就是我在Oracle文档中找到的内容:

  

在另一个用户中创建触发器   架构,或引用表中的   来自你的触发器的另一个模式   架构,你必须有CREATE ANY   TRIGGER系统特权。有了这个   特权,可以创建触发器   在任何架构中都可以关联   与任何用户的表。此外,   创建触发器的用户必须   也有EXECUTE特权   引用的程序,函数或   包。

此处:Oracle Doc

所以我认为这应该可行,但我不确定它在文档中提到的“EXECUTE特权”。

3 个答案:

答案 0 :(得分:5)

您遇到的是Oracle安全模型的一项功能。使用模式的全部目的是控制对数据的访问。我的架构中的表格是 mine ,在我授予您特权之前,您甚至无法看到它们。

语法非常简单:所有者架构问题

grant select, insert on my_table to you
/

或者,具有GRANT ANY权限的帐户(例如DBA)可以在任何用户的对象上传递权限。

grant select, insert on apc.my_table to you
/

被授权者可以是用户,也可以是角色。但请注意,我们只能使用直接授予用户的权限来构建程序单元 - 存储过程,视图,触发器。

因此,如果您让其他架构所有者授予您必要的权限,您将能够构建触发器。

修改

在引用另一个模式中的对象时,我们需要使用模式名称来限定对象....

insert into apc.whatever_table  values ...

或者我们需要为它创建一个同义词

create synonym whatever for apc.whatever_table;

答案 1 :(得分:2)

我觉得有人应该添加明显的 - 其他模式的表必须使用模式名称限定,或者需要私有/公共同义词。我想知道原始问题是否仅仅是一个名称解析问题。如果没有,APC的答案就是对Oracle安全模型的一个很好的解释。

答案 2 :(得分:0)

您应该为所涉及的每个表和模式执行此操作:

grant select on OTHER_SCHEMA_%.table_name to MAIN_SCHEMA;