1つ、DMLトリガー
トリガーの機能は、イベントが発生したときに実行ブロック内のコンテンツを自動的に実行することです。
トリガーは、テーブルまたはビューに作用し、挿入、更新、または削除操作の前、最中、または後に実行される特定のプログラムセグメントを指定できます。
CREATE [OR REPLACE] TRIGGER triggername
BEFORE/INSTEAD OF/AFTER ---选择事件触发(前,时,后)执行 PL/SQL代码块
[INSERT [OR] UPDATE [OR] DELETE] ---当执行 插入 、更新、删除前触发
ON tblname_or_viewname ---确认作用的表或者视图
[Referencing {OLD [AS] old / NEW [AS] new }]
[FOR EACH ROW] --指定行级触发器,不指定就是表级触发器
[WHEN (condition)] --当符合condition的条件满足时触发
DECLARE
-- local variables here
BEGIN
;--PL/SQL block
END triggername ;
sqlserverで削除されたのは、Oracle:oldに対応する、更新および削除される古い情報を格納するための一時テーブルです。Insertedは、Oracle:newに対応する、挿入および更新されようとしている新しい情報を格納するための一時テーブルです。:newと:oldは、データセット全体を表すのではなく、操作対象のデータの行を表すため、通常、[FOR EACH ROW]は、これら2つを使用する場合の行トリガーを示すために追加されます。その中で、更新の操作は、実際には、データを最初に古いものに入れ、次に削除してから新しいデータを新しいものに入れてデータベースに挿入することです。
古いデータが保存されているため、古いデータが削除または変更されようとしているため、古いデータを更新しても意味がありません。操作が完了した後にトリガーされた後は、この時点で新しいデータを操作しても意味がありません。後の場合、:newのレコードは変更できません。
マルチテーブルビューの場合、テーブルの内容を保持するようにキーを変更することができます。単一テーブルビューjでDML操作を実行することもできます。
テーブルレベルのトリガーは、テーブルまたはビューイベントがトリガーされたときに1回だけ実行されます。テーブルまたはビューイベントで行レベルのトリガーがトリガーされると、データの行が影響を受けるたびにプログラムブロックのコンテンツが1回実行されます。
ロールバック、コミット、およびDDLステートメントはDMLトリガーでは使用できません。
新しい練習テーブルdepartment_tblを作成します。
次のトリガーを作成して、効果を比較します
create view VW_department_tbl as select * from department_tbl;
--------insert视图VW_department_tbl时,给每行数据Leaders 默认值'BOSS'----
create or replace trigger departInsertDefault2
Instead of insert --替换原有的insert语句,且Instead Of 只能作用于视图, WHEN不能用于 INSTEAD OF
on VW_department_tbl
FOR EACH ROW
declare
begin
if :new.leaders is null then
insert into department_tbl values(:new.department,:new.all_salary,'BOSS');
else
insert into department_tbl values(:new.department,:new.all_salary,:new.leaders);
end if;
end departInsertDefault2 ;
drop trigger departInsertDefault2;
-----------------------------------
--------insert表department_tbl时,给每行数据Leaders 默认值'BOSS'----
create or replace trigger departInsertDefault1
before insert
on department_tbl
FOR EACH ROW
WHEN (new.leaders is null
)declare
begin
:new.leaders :='BOSS';
end departInsertDefault1 ;
drop trigger departInsertDefault1;
トリガー2で実行
トリガー1で実行
新しいトリガー3、
create or replace procedure dep_insert(dep in department_tbl.department%type ,sal in department_tbl.all_salary%type)
is PRAGMA AUTONOMOUS_TRANSACTION; --自主事物处理
begin
insert into department_tbl values(dep,sal,'BOSS');
--update department_tbl set leaders='BOSS' where leaders is null and department = dep; --取不到还未提交的数据
commit;
end dep_insert;
/
create or replace trigger departInsertDefault3
after insert --after 无法修改基表的数据,需要自主事物处理的存储过程配合,且新数据属于未提交状态
on department_tbl
FOR EACH ROW
WHEN (new.leaders is null)
declare
v_data department_tbl%rowtype;
begin
--update department_tbl set leaders='BOSS' where leaders is null and department = :new.department; --无法执行
dep_insert( :new.department,:new.all_salary);
end departInsertDefault3 ;
drop trigger departInsertDefault3;
実施した
つまり、データを変更する場合は、データ検証に適した前、後を使用することをお勧めします。代わりに、ビューにのみ使用できます。
更新例:
create or replace trigger departInsertDefault4
before update
on department_tbl
FOR EACH ROW
when (old.department = new.department)
declare
begin
:new.all_salary := :new.all_salary+:old.all_salary;
end departInsertDefault4 ;
/
--drop trigger departInsertDefault4;
truncate table department_tbl;
insert into department_tbl(department,all_salary) values('部门1',2000);
insert into department_tbl(department,all_salary,leaders) values('部门1',2000,'BOSS');
insert into department_tbl(department,all_salary,leaders) values('部门2',3000,'雇佣者1');
update department_tbl set department = '部门999' where Leaders is not null;
update department_tbl set Leaders = 'boss' where Leaders is not null;
commit;
select * from department_tbl;
最終的な実行結果:
2、モード(DDL)トリガー
Create table obj_tbl(
obj_name varchar2(30),
obj_type varchar2(20),
obj_date Date
)
create or replace trigger obj_trigger
after Create --alter drop
on SCHEMA
BEGIN
insert into obj_tbl values( ora_dict_obj_name,ora_dict_obj_type,SYSDATE);
END;
/
ora_client_ip_address | クライアントのIPアドレスを返すために使用されます |
ora_database_name | 現在のデータベース名を返すために使用されます |
ora_des_encrypted_password | DES暗号化ユーザーパスワードを返すために使用されます |
ora_dict_obj_name | DDL操作に対応するデータベースオブジェクト名を返すために使用されます |
ora_dict_obj_name_list(name_list_ OUT ora_name_list_t) | ワードイベントで変更されたオブジェクト名のリストを返すために使用されます |
ora_dict_obj_owner | DDL操作に対応するオブジェクトの所有者名を返すために使用されます。 |
ora_dict_obj_ower_list(ower_list OUT ora_name_list_t) | イベントで変更されたオブジェクトの所有者のリストを返すために使用されます |
ora_dict_obj_type | DDL操作に対応するデータベースオブジェクトのタイプを返すために使用されます。 |
ora_grantee(user_list OUT ora_name_list_t) | 承認中にイベント承認者を返すために使用されます。 |
ora_instance_num | コース番号を返すために使用されます。 |
ora_is_alter_column(column_name IN VARCHAR2) | 特定の列が変更されたかどうかを検出するために使用されます |
ora_is_creating_nested_table | ネストされたテーブルが作成されているかどうかを検出するために使用されます |
ora_is_drop_column(column_name IN VARCHAR2) | 特定の列が削除されたかどうかを検出するために使用されます |
ora_is_servererror(error_number) | 特定のOracleエラーが返されたかどうかを検出するために使用されます。 |
ora_login_user | ログインユーザー名を返すために使用されます |
ora_sysevent | トリガーをトリガーしたシステム時刻の名前を返すために使用されます。 |
3つのデータベースレベルのトリガー
----数据库启动触发器-----
create or replace trigger db_trigger
after startup on database
begin
insert into obj_tbl values( ora_sysevent,null,SYSDATE);
end;
/
----数据库用户登录触发器-----
create or replace trigger user_trigger
after logon on database
begin
insert into obj_tbl values( ora_login_user,ora_client_ip_address,SYSDATE);
end;
/
第四に、トリガーの操作
alter tigger tiggername ENABLE / DISABLEトリガーを開閉します
select * from dba_triggers / user_triggersクエリトリガー情報