Tables_Historyという名前の表にすべての表の変更を記録したいのですが、表ごとに1つのトリガーがあり、明示的なアドレス指定列名はなく、列のタイプに応じています。私は異なるプロジェクトに属する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を変更+コピーすることができます)1台のための私の理想的なトリガーです:
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
私はトリガーを使用してそれが可能だとは思わない。たとえそれを動的にしても、それはうまくいくとは思えません。 btwなぜこのようにしたいのですか? – XING
この点についてもう少し詳しく説明します。トリガーをどのように見せたいか教えてください。必要なサンプルコードまたは出力を共有します。 –