我想在Oracle DB上记录到该时间执行的所有DDL操作的历史记录。
我为此创建了一个TABLE
和一个DDL TRIGGER
:
CREATE TABLE AUDIT_DDL (
D DATE,
OSUSER VARCHAR2(255),
CURRENT_USER VARCHAR2(255),
HOST VARCHAR2(255),
TERMINAL VARCHAR2(255),
OWNER VARCHAR2(30),
TYPE VARCHAR2(30),
NAME VARCHAR2(30),
SYSEVENT VARCHAR2(30));
--/
CREATE OR REPLACE TRIGGER AUDIT_DDL_TRG AFTER DDL ON SCHEMA
BEGIN
IF (ORA_SYSEVENT='TRUNCATE')
THEN
NULL;
ELSE
INSERT INTO AUDIT_DDL(D, OSUSER,CURRENT_USER,HOST,TERMINAL,OWNER,TYPE,NAME,SYSEVENT)
VALUES(
SYSDATE,
SYS_CONTEXT('USERENV','OS_USER') ,
SYS_CONTEXT('USERENV','CURRENT_USER') ,
SYS_CONTEXT('USERENV','HOST') ,
SYS_CONTEXT('USERENV','TERMINAL') ,
ORA_DICT_OBJ_OWNER,
ORA_DICT_OBJ_TYPE,
ORA_DICT_OBJ_NAME,
ORA_SYSEVENT
);
END IF;
END;
/
这很正常:在每个DDL语句之后,我在AUDIT_DDL表中有一个新行。
但是我仍然没有有关确切操作类型的任何信息。
例如,以下两个语句将在AUDIT_DDL表中产生相同的ALTER
SYSEVENT:
ALTER TABLE MYTABLE RENAME COLUMN TEMP TO NEWTEMP;
ALTER TABLE MYTABLE DROP COLUMN NEWTEMP;
因此,以这种方式,我不知道执行了什么操作,而不是通用的ALTER TABLE
,甚至不知道TEMP列是否已重命名或从表MYTABLE中删除!
我的问题是:如何在执行DDL之后检索有关事件发生的更多信息(所涉及的对象,详细信息等)?
答案 0 :(得分:1)
检查以下内容:
删除触发器AUDIT_DDL_TRG
drop trigger AUDIT_DDL_TRG
创建新列
alter table AUDIT_DDL add statements varchar2(1000);
再次运行触发器
CREATE OR REPLACE TRIGGER AUDIT_DDL_TRG
AFTER DDL ON SCHEMA
DECLARE
sql_text ora_name_list_t;
v_stmt VARCHAR2(2000);
n PLS_INTEGER;
BEGIN
n := ora_sql_txt(sql_text);
FOR i IN 1 .. n LOOP
v_stmt := v_stmt || sql_text(i);
END LOOP;
v_stmt :=regexp_replace(v_stmt,
'rename[[:space:]]+.*[[:space:]]+to[[:space:]]+([a-z0-9_]+)',
'\1',
1,
1,
'i');
IF (ORA_SYSEVENT = 'TRUNCATE') THEN
NULL;
ELSE
INSERT INTO AUDIT_DDL
(D,
OSUSER,
CURRENT_USER,
HOST,
TERMINAL,
OWNER,
TYPE,
NAME,
SYSEVENT,
statements)
VALUES
(SYSDATE,
SYS_CONTEXT('USERENV', 'OS_USER'),
SYS_CONTEXT('USERENV', 'CURRENT_USER'),
SYS_CONTEXT('USERENV', 'HOST'),
SYS_CONTEXT('USERENV', 'TERMINAL'),
ORA_DICT_OBJ_OWNER,
ORA_DICT_OBJ_TYPE,
ORA_DICT_OBJ_NAME,
ORA_SYSEVENT,
v_stmt);
END IF;
END;
/
进行一些更改,您将看到以下语句