[英]Missing privilege - Oracle System event trigger problem 12c
我有一個系統事件觸發器。 在我嘗試將代碼移至其他數據庫之前,它一直運行良好。 我犯了一個錯誤:忘記導出原始用戶,所以我創建了一個新用戶。
因此,在發布代碼后,我得到了錯誤:
TRIGGER ORACLE_VERSION_CONTROLLER.TRG_CATCH_AFTER_DDL的編譯錯誤
錯誤:PLS-00201:必須聲明標識符'ORA_SQL_TXT'行:24文本:n:= ora_sql_txt(sql_text);
錯誤:PL / SQL:語句被忽略行:24文本:n:= ora_sql_txt(sql_text);
有人有主意嗎?
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;
我可以從非系統用戶創建此觸發器。
-- 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;
輸出:
希望對您有用。
干杯!!
解決方案是該功能必須在sys用戶下並具有執行特權。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.