我想记录一个名为Tables_History的表中的所有表更改,每个表具有一个触发器,并且没有寻址列名称的明确性,并且根据列的类型。因为我有50张桌子,因为有不同的项目。许多开发人员可能会更改表格的结构。所以我不能列出明确的列名。这是Tables_History的defenition:在Oracle中审计DML更改
create table Tables_History
(
user_id VARCHAR2(10) not null,
change_date DATE not null,
table_name VARCHAR2(100) not null,
column_name VARCHAR2(100) not null,
primary_key_id INTEGER not null,
old_number NUMBER,
new_number NUMBER,
old_string VARCHAR2(900),
new_string VARCHAR2(900),
old_date DATE,
new_date DATE,
...
.
);
如果有任何的方式来访问:在触发新的列值,通过将列名作为参数,而不是标准的方式(:new.column_name)。像这样(:new ['column_name'])。
这是我为一个表(然后我可以复制粘贴+这触发其他表,改变只有几参数:-D)理想触发:
create or replace trigger Audit_TableName
before update on TableName
for each row
declare
v_query varchar(32767);
UserCode varchar(10);
begin
SELECT sys_context('USERENV', 'CLIENT_IDENTIFIER')
INTO UserCode
FROM DUAL;
FOR getrec IN (SELECT column_name, data_type
FROM all_tab_columns
WHERE table_name = 'TableName'
AND owner = 'MEHRAN'
AND data_type <> 'BLOB') LOOP
if Updating(getrec.column_name) then
if getrec.data_type = 'NUMBER' then
v_query := 'insert into Tables_History(user_id,change_date,table_name,column_name,primary_key_id,,,OLD_NUMBER, NEW_NUMBER)'
||'values('..,..,..,..||:old[getrec.column_name]||','||:new[getrec.column_name]||')';
else if getrec.data_type = 'VARCHAR2' then
v_query := 'insert into Tables_History(...,...,... OLD_VARCHAR, NEW_VARCHAR)'
||'values(...,...,..'||:old[getrec.column_name]||','||:new[getrec.column_name]||')';
...
.
.
end if;
EXECUTE IMMEDIATE v_query;
end if;
END LOOP;
end Audit_TableName;
尝试打印您构建的动态查询;这会给你一些提示来编辑你的代码 – Aleksej
我不认为这是可能的使用触发器。即使你把它变成动态的,我怀疑它会起作用。顺便说一句,你为什么要这样做。 – XING
在这方面提供一些更多的细节。告诉我们你希望你的触发器看起来一样吗?共享您需要的示例代码或输出。 –