我有一个系统事件触发器。在我尝试将代码移至其他数据库之前,它一直运行良好。 我犯了一个错误:忘记导出原始用户,所以我创建了一个新用户。
因此,在发布代码后,我得到了错误:
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;
答案 0 :(得分:2)
我能够从非系统用户创建此触发器。
-- 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;
输出:
希望,对您有用。
干杯!
答案 1 :(得分:1)
解决方案是该功能必须在sys用户下并具有执行特权。