wal*_*ood 4 database oracle triggers oracle10g ora-00942
我正在尝试编写一个表触发器,用于查询触发器所在架构之外的另一个表.这可能吗?在我的架构中查询表似乎没有问题,但我得到:
Error: ORA-00942: table or view does not exist
Run Code Online (Sandbox Code Playgroud)
尝试查询我的架构外的表时.
编辑
我很抱歉第一次没有提供尽可能多的信息.我的印象是这个问题更简单.
我正在尝试在一个表上创建一个触发器,该表根据某些数据的存在来更改新插入行上的某些字段,这些数据可能存在于另一个模式中的表中,也可能不存在.
我用来创建触发器的用户帐户确实具有独立运行查询的权限.事实上,我有触发器打印我正在尝试运行的查询,并且能够成功运行它.
我还应该注意,我正在使用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;
Run Code Online (Sandbox Code Playgroud)
使用前面提到的错误,触发器在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
Run Code Online (Sandbox Code Playgroud)
我有以下系统权限(USER_SYS_PRIVS):
USERNAME PRIVILEGE ADMIN_OPTION
ME ALTER ANY TRIGGER NO
ME CREATE ANY TRIGGER NO
ME UNLIMITED TABLESPACE NO
Run Code Online (Sandbox Code Playgroud)
这就是我在Oracle文档中找到的内容:
要在另一个用户的模式中创建触发器,或者从模式中的触发器引用另一个模式中的表,您必须具有CREATE ANY TRIGGER系统特权.使用此权限,可以在任何模式中创建触发器,并且可以将触发器与任何用户的表关联.此外,创建触发器的用户还必须对引用的过程,函数或包具有EXECUTE特权.
这里:Oracle Doc
因此,在我看来这应该可行,但我不确定它在文档中提到的"EXECUTE特权".
您遇到的是Oracle安全模型的一个特性.使用模式的全部目的是控制对数据的访问.我的架构中的表是我的,在我授予您特权之前,您甚至无法看到它们.
语法非常简单:所有者架构问题
grant select, insert on my_table to you
/
Run Code Online (Sandbox Code Playgroud)
或者,具有GRANT ANY特权的帐户(例如DBA)可以在任何用户的对象上传递特权.
grant select, insert on apc.my_table to you
/
Run Code Online (Sandbox Code Playgroud)
被授予者可以是用户或角色.但请注意,我们只能使用直接授予用户的权限来构建程序单元 - 存储过程,视图,触发器.
因此,如果您让其他架构所有者授予您必要的权限,您将能够构建触发器.
编辑
在引用另一个模式中的对象时,我们需要使用模式名称限定对象....
insert into apc.whatever_table values ...
Run Code Online (Sandbox Code Playgroud)
否则我们需要为它创建一个同义词
create synonym whatever for apc.whatever_table;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10369 次 |
最近记录: |