[英]Missing privilege - Oracle System event trigger problem 12c
I have a system event trigger. 我有一个系统事件触发器。 It worked fine until I tried to move the code to a different database. 在我尝试将代码移至其他数据库之前,它一直运行良好。 I made a mistake: forgot to export the original user, so I created a total new one. 我犯了一个错误:忘记导出原始用户,所以我创建了一个新用户。
So after I release my code I get the error: 因此,在发布代码后,我得到了错误:
Compilation errors for TRIGGER ORACLE_VERSION_CONTROLLER.TRG_CATCH_AFTER_DDL TRIGGER ORACLE_VERSION_CONTROLLER.TRG_CATCH_AFTER_DDL的编译错误
Error: PLS-00201: identifier 'ORA_SQL_TXT' must be declared Line: 24 Text: n := ora_sql_txt(sql_text); 错误:PLS-00201:必须声明标识符'ORA_SQL_TXT'行:24文本:n:= ora_sql_txt(sql_text);
Error: PL/SQL: Statement ignored Line: 24 Text: n := ora_sql_txt(sql_text); 错误:PL / SQL:语句被忽略行:24文本:n:= ora_sql_txt(sql_text);
Anyone has an idea? 有人有主意吗?
CREATE OR REPLACE TRIGGER trg_catch_after_ddl
AFTER DDL ON DATABASE
DECLARE
sql_text ora_name_list_t;
n pls_integer;
v_sql CLOB;
v_id NUMBER;
BEGIN
dbms_output.put_line(ora_sysevent);
IF ora_sysevent IN ('DROP', 'ALTER', 'ANALYZE') THEN
/*alter table must be handle*/
NULL; -- this is not finished
ELSE
IF ora_dict_obj_type = 'TABLE' THEN
v_sql := dbms_metadata.get_ddl(ora_dict_obj_type,
ora_dict_obj_name,
ora_login_user);
ELSE
n := ora_sql_txt(sql_text);
FOR i IN 1 .. n LOOP
v_sql := v_sql || sql_text(i);
END LOOP;
END IF;
INSERT INTO audit_log
(user_name, dll_type, object_name, object_type, object_script)
VALUES
(ora_login_user,
ora_sysevent,
ora_dict_obj_name,
ora_dict_obj_type,
v_sql)
RETURNING log_id INTO v_id;
pcd_source_writer(id => v_id);
END IF;
END trg_catch_after_ddl;
I am able to create this trigger from the non-sys user. 我可以从非系统用户创建此触发器。
-- Execute from sys user
CREATE USER T IDENTIFIED BY <Password>
default tablespace <Default_tablespace>;
ALTER USER T QUOTA UNLIMITED ON <Default_tablespace>;
GRANT CONNECT, RESOURCE TO T;
GRANT ADMINISTER DATABASE TRIGGER TO T;
-- -
-- Execute from T user
CREATE TABLE AUDIT_LOG (
LOG_ID NUMBER
GENERATED ALWAYS AS IDENTITY,
USER_NAME VARCHAR2(4000),
DLL_TYPE VARCHAR2(4000),
OBJECT_NAME VARCHAR2(4000),
OBJECT_TYPE VARCHAR2(4000),
OBJECT_SCRIPT CLOB
);
CREATE OR REPLACE TRIGGER TRG_CATCH_AFTER_DDL AFTER DDL ON DATABASE DECLARE
SQL_TEXT ORA_NAME_LIST_T;
N PLS_INTEGER;
V_SQL CLOB;
V_ID NUMBER;
BEGIN
DBMS_OUTPUT.PUT_LINE(ORA_SYSEVENT);
IF ORA_SYSEVENT IN (
'DROP',
'ALTER',
'ANALYZE'
) THEN
/*alter table must be handle*/
NULL; -- this is not finished
ELSE
IF ORA_DICT_OBJ_TYPE = 'TABLE' THEN
V_SQL := DBMS_METADATA.GET_DDL(ORA_DICT_OBJ_TYPE, ORA_DICT_OBJ_NAME, ORA_LOGIN_USER);
ELSE
N := ORA_SQL_TXT(SQL_TEXT);
FOR I IN 1..N LOOP
V_SQL := V_SQL || SQL_TEXT(I);
END LOOP;
END IF;
INSERT INTO audit_log
(user_name, dll_type, object_name, object_type, object_script)
VALUES
(ora_login_user,
ora_sysevent,
ora_dict_obj_name,
ora_dict_obj_type,
v_sql)
RETURNING log_id INTO v_id;
--
-- pcd_source_writer(id => v_id);
END IF;
END TRG_CATCH_AFTER_DDL;
/
-- -
-- Testing:
DROP SEQUENCE TEMP_SEQ;
CREATE SEQUENCE TEMP_SEQ START WITH 1 INCREMENT BY 1 MAXVALUE 100;
ALTER SEQUENCE TEMP_SEQ INCREMENT BY 2;
-- -
-- Result:
SELECT * FROM audit_log;
Output: 输出:
Hope, It will be useful to you. 希望对您有用。
Cheers!! 干杯!!
解决方案是该功能必须在sys用户下并具有执行特权。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.