1、數據庫觸發器是一個與表相關聯的、存儲的PL/SQL程序。每當一個特定的數據操作語句(Insert,update,delete)在指定的表上發出時,Oracle自動地執行觸發器中定義的語句序列。
2、觸發器的類型
語句級觸發器
在指定的操作語句操作之前或之後執行一次,不管這條語句影響了多少行 。
行級觸發器(FOR EACH ROW)
觸發語句作用的每一條記錄都被觸發。在行級觸發器中使用old和new僞記錄變量, 識別值的狀態。
3、例子:
一、語句級觸發器:
--當成功插入一個新員工後,自動打印“成功插入新員工”
create trigger sayNewEmp
after insert --作用那個操作(之前還是之後)
on emp --作用在那個表
begin
dbms_output.put_line('成功插入新員工');
end;
/
二、行級觸發器:
/*
數據確認
漲後的工資不能少於漲前的工資
*/
create or replace trigger checksal
before update
on emp
for each row --行級觸發器 也就是說數據庫中的每一行都要檢查(每一行都對應一個員工);
begin
--if 漲後的薪水 < 漲前的薪水 then
if :new.sal < :old.sal then
raise_application_error(-20002,'漲後的薪水不能少於漲前的薪水,漲前:'||:old.sal||' 漲後:'||:new.sal);
end if;
end;
/
4、不同服務器,不同數據庫:
--不同服務器數據庫之間的數據操作
--************************************************************************************
1、
--創建鏈接服務器
exec
sp_addlinkedserver
'ITSV'
,
' '
,
'SQLOLEDB'
,
'遠程服務器名或ip地址 '
exec
sp_addlinkedsrvlogin
'ITSV'
,
'false '
,
null
,
'用戶名'
,
'密碼'
2、啓動兩臺服務器的MSDTC服務
MSDTC服務提供分佈式事務服務,如果要在數據庫中使用分佈式事務,必須在參與的雙方服務器啓動MSDTC(Distributed
Transaction
Coordinator)服務。
3、打開雙方的135端口
MSDTC服務依賴於RPC(Remote
Procedure
Call (RPC))服務,RPC使用135端口,保證RPC服務啓動,如果服務器有防火牆,保證135端口不被防火牆擋住。
使用“telnet IP 135”命令測試對方端口是否對外開放。也可用端口掃描軟件(比如Advanced Port Scanner)掃描端口以判斷端口是否開放
4、
--如要創建觸發器
create
trigger
t_test
on
test
for
insert
,
update
,
delete
as
--加上下面兩句,否則會提示新事務不能登記到指定事務處理器
set
xact_abort
on
begin
distributed tran
delete
from
openrowset(
'sqloledb'
,
'xz'
;
'sa'
;
''
,test.dbo.test)
where
id
in
(
select
id
from
deleted)
insert
into
openrowset(
'sqloledb'
,
'xz'
;
'sa'
;
''
,test.dbo.test)
select
*
from
inserted
commit
tran
--查詢示例
select
*
from
ITSV.數據庫名.dbo.表名
--導入示例
select
*
into
表
from
ITSV.數據庫名.dbo.表名
--以後不再使用時刪除鏈接服務器
exec
sp_dropserver
'ITSV '
,
'droplogins '
5、如果同一個服務器,不同的數據庫(insert):
一,user and org_employee同步:
use sgcadrept
go
create trigger save_employee --定義觸發器
on org_employee --作用在那個表
for insert --行級觸發器
as
--begin
declare @userid varchar(60)
declare @loginname varchar(60)
declare @username varchar(100)
declare @userpwd varchar(50)
declare @state char(1)
declare @logintime varchar(20)
declare @creator varchar(60)
declare @organid varchar(100)
declare @organ varchar(200)
select @userid = empid from inserted
select @loginname = userid from inserted
select @username = empname from inserted
select @userpwd = 'e67c10a4c8fbfc0c400e047bb9a056a1'
select @state = '1'
select @logintime = GETDATE()
select @creator = 'admin'
select @organid = orgid from inserted
select @organ = orgname from org_organization where orgid = @organid
insert into ptzaozhuang.dbo.p_user (ptzaozhuang.dbo.p_user.userid,ptzaozhuang.dbo.p_user.loginname,ptzaozhuang.dbo.p_user.username
,ptzaozhuang.dbo.p_user.userpwd,ptzaozhuang.dbo.p_user.state,ptzaozhuang.dbo.p_user.logintime
,ptzaozhuang.dbo.p_user.creator,ptzaozhuang.dbo.p_user.organid,ptzaozhuang.dbo.p_user.organ) values(
@userid,@loginname,@username,@userpwd,@state,@logintime,@creator,@organid,@organ)
--end
delete同步:
use sgcadrept
go
create trigger delete_employee
on org_employee
for delete
as
--begin
declare @userid varchar(60)
select @userid = empid from deleted
update ptzaozhuang.dbo.p_user set ptzaozhuang.dbo.p_user.state='0' where
ptzaozhuang.dbo.p_user.userid=@userid
--end
update同步:
use sgcadrept
go
create trigger update_employee
on org_employee
for update
as
--begin
declare @userid varchar(60)
declare @loginname varchar(60)
declare @username varchar(100)
declare @userpwd varchar(50)
declare @state char(1)
declare @logintime varchar(20)
declare @creator varchar(60)
declare @organid varchar(100)
declare @organ varchar(200)
select @userid = empid from inserted
select @loginname = userid from inserted
select @username = empname from inserted
select @userpwd = 'e67c10a4c8fbfc0c400e047bb9a056a1'
select @state = '1'
select @logintime = GETDATE()
select @creator = 'admin'
select @organid = orgid from inserted
select @organ = orgname from org_organization where orgid = @organid
update ptzaozhuang.dbo.p_user set
ptzaozhuang.dbo.p_user.loginname=@loginname,ptzaozhuang.dbo.p_user.username=@username
,ptzaozhuang.dbo.p_user.userpwd=@userpwd,ptzaozhuang.dbo.p_user.state=@state,ptzaozhuang.dbo.p_user.logintime=@logintime
,ptzaozhuang.dbo.p_user.creator=@creator,ptzaozhuang.dbo.p_user.organid=@organid,ptzaozhuang.dbo.p_user.organ=@organ
where
ptzaozhuang.dbo.p_user.userid=@userid
--end
二,xz08 and org_organization 同步:
use sgcadrept
go
create trigger save_organization --定義觸發器
on org_organization --作用在那個表
for insert --行級觸發器
as
--begin
declare @code varchar(8)
declare @code_name varchar(80)
declare @code_abr1 varchar(80)
declare @code_abr2 varchar(80)
declare @code_level float(53)
declare @is_leaf char(1) --臨時字段 判斷轉換使用
declare @code_leaf char(1)
declare @sup_code varchar(8)
declare @code_assist varchar(10)
declare @invalid varchar(2)
declare @code_aname varchar(100)
declare @start_date varchar(8)
declare @stop_date varchar(8)
declare @iscustom char(1)
select @code = orgid from inserted
select @code_name = orgname from inserted
select @code_abr1 = @code_name
select @code_abr2 = @code_name
select @code_level = orglevel from inserted
select @is_leaf = isleaf from inserted
if @is_leaf<>'n' --判斷轉換
select @code_leaf = '1'
if @is_leaf<>'y'
select @code_leaf = '0'
select @sup_code = parentorgid from inserted --轉換
select @code_assist = '1'
select @invalid = '1'
select @code_aname = @code_name
select @start_date = startdate from inserted
select @stop_date = enddate from inserted
select @iscustom = '1'
insert into ptzaozhuang.dbo.xz08 (ptzaozhuang.dbo.xz08.code,ptzaozhuang.dbo.xz08.code_name,ptzaozhuang.dbo.xz08.code_abr1
,ptzaozhuang.dbo.xz08.code_abr2,ptzaozhuang.dbo.xz08.code_level,ptzaozhuang.dbo.xz08.code_leaf
,ptzaozhuang.dbo.xz08.sup_code,ptzaozhuang.dbo.xz08.code_assist,ptzaozhuang.dbo.xz08.invalid,ptzaozhuang.dbo.xz08.code_aname,ptzaozhuang.dbo.xz08.start_date
,ptzaozhuang.dbo.xz08.stop_date,ptzaozhuang.dbo.xz08.iscustom) values(
@code,@code_name,@code_abr1,@code_abr2,@code_level,@code_leaf,@sup_code,@code_assist,@invalid,@code_aname,@start_date,@stop_date,@iscustom)
--end
delete同步:
update同步:
use sgcadrept
go
create trigger update_organization --定義觸發器
on org_organization --作用在那個表
for update --行級觸發器
as
--begin
declare @code varchar(8)
declare @code_name varchar(80)
declare @code_abr1 varchar(80)
declare @code_abr2 varchar(80)
declare @code_level float(53)
declare @is_leaf char(1) --臨時字段 判斷轉換使用
declare @code_leaf char(1)
declare @sup_code varchar(8)
declare @code_assist varchar(10)
declare @invalid varchar(2)
declare @code_aname varchar(100)
declare @start_date varchar(8)
declare @stop_date varchar(8)
declare @iscustom char(1)
select @code = orgid from inserted
select @code_name = orgname from inserted
select @code_abr1 = @code_name
select @code_abr2 = @code_name
select @code_level = orglevel from inserted
select @is_leaf = isleaf from inserted
if @is_leaf<>'n' --判斷轉換
select @code_leaf = '1'
if @is_leaf<>'y'
select @code_leaf = '0'
select @sup_code = parentorgid from inserted --轉換
select @code_assist = '1'
select @invalid = '1'
select @code_aname = @code_name
select @start_date = startdate from inserted
select @stop_date = enddate from inserted
select @iscustom = '1'
update ptzaozhuang.dbo.xz08 set
ptzaozhuang.dbo.xz08.code_name=@code_name,ptzaozhuang.dbo.xz08.code_abr1=@code_abr1
,ptzaozhuang.dbo.xz08.code_abr2=@code_abr2,ptzaozhuang.dbo.xz08.code_level=@code_level,ptzaozhuang.dbo.xz08.code_leaf=@code_leaf
,ptzaozhuang.dbo.xz08.sup_code=@sup_code,ptzaozhuang.dbo.xz08.code_assist=@code_assist,ptzaozhuang.dbo.xz08.invalid=@invalid
,ptzaozhuang.dbo.xz08.code_aname=@code_aname,ptzaozhuang.dbo.xz08.start_date=@start_date,ptzaozhuang.dbo.xz08.stop_date=@stop_date
,ptzaozhuang.dbo.xz08.iscustom=@iscustom
where
ptzaozhuang.dbo.xz08.code=@code
--end
-------------------------------------------------------------------------------------------------------------------
use sgcadrept
go
create trigger save_employee --定義觸發器
on org_employee --作用在那個表
for insert --行級觸發器
as
--begin
declare @userid varchar(60)
declare @loginname varchar(60)
declare @username varchar(100)
declare @userpwd varchar(50)
declare @state char(1)
declare @logintime varchar(20)
declare @creator varchar(60)
declare @organid varchar(100)
declare @organ varchar(200)
select @userid = empid from inserted
select @loginname = userid from inserted
select @username = empname from inserted
select @userpwd = 'e67c10a4c8fbfc0c400e047bb9a056a1'
select @state = '1'
select @logintime = GETDATE()
select @creator = 'admin'
select @organid = orgid from inserted
select @organ = orgname from org_organization where orgid = @organid
insert into ptzaozhuang.dbo.p_user (ptzaozhuang.dbo.p_user.userid,ptzaozhuang.dbo.p_user.loginname,ptzaozhuang.dbo.p_user.username
,ptzaozhuang.dbo.p_user.userpwd,ptzaozhuang.dbo.p_user.state,ptzaozhuang.dbo.p_user.logintime
,ptzaozhuang.dbo.p_user.creator,ptzaozhuang.dbo.p_user.organid,ptzaozhuang.dbo.p_user.organ) values(
@userid,@loginname,@username,@userpwd,@state,@logintime,@creator,@organid,@organ)
--end
go
create trigger delete_employee
on org_employee
for delete
as
--begin
declare @userid varchar(60)
select @userid = empid from deleted
update ptzaozhuang.dbo.p_user set ptzaozhuang.dbo.p_user.state='0' where
ptzaozhuang.dbo.p_user.userid=@userid
--end
go
create trigger update_employee
on org_employee
for update
as
--begin
declare @userid varchar(60)
declare @loginname varchar(60)
declare @username varchar(100)
declare @userpwd varchar(50)
declare @state char(1)
declare @logintime varchar(20)
declare @creator varchar(60)
declare @organid varchar(100)
declare @organ varchar(200)
select @userid = empid from inserted
select @loginname = userid from inserted
select @username = empname from inserted
select @userpwd = 'e67c10a4c8fbfc0c400e047bb9a056a1'
select @state = '1'
select @logintime = GETDATE()
select @creator = 'admin'
select @organid = orgid from inserted
select @organ = orgname from org_organization where orgid = @organid
update ptzaozhuang.dbo.p_user set
ptzaozhuang.dbo.p_user.loginname=@loginname,ptzaozhuang.dbo.p_user.username=@username
,ptzaozhuang.dbo.p_user.userpwd=@userpwd,ptzaozhuang.dbo.p_user.state=@state,ptzaozhuang.dbo.p_user.logintime=@logintime
,ptzaozhuang.dbo.p_user.creator=@creator,ptzaozhuang.dbo.p_user.organid=@organid,ptzaozhuang.dbo.p_user.organ=@organ
where
ptzaozhuang.dbo.p_user.userid=@userid
--end
go
create trigger save_organization --定義觸發器
on org_organization --作用在那個表
for insert --行級觸發器
as
--begin
declare @code varchar(8)
declare @code_name varchar(80)
declare @code_abr1 varchar(80)
declare @code_abr2 varchar(80)
declare @code_level float(53)
declare @is_leaf char(1) --臨時字段 判斷轉換使用
declare @code_leaf char(1)
declare @sup_code varchar(8)
declare @code_assist varchar(10)
declare @invalid varchar(2)
declare @code_aname varchar(100)
declare @start_date varchar(8)
declare @stop_date varchar(8)
declare @iscustom char(1)
select @code = orgid from inserted
select @code_name = orgname from inserted
select @code_abr1 = @code_name
select @code_abr2 = @code_name
select @code_level = orglevel from inserted
select @is_leaf = isleaf from inserted
if @is_leaf<>'n' --判斷轉換
select @code_leaf = '1'
if @is_leaf<>'y'
select @code_leaf = '0'
select @sup_code = parentorgid from inserted --轉換
select @code_assist = '1'
select @invalid = '1'
select @code_aname = @code_name
select @start_date = startdate from inserted
select @stop_date = enddate from inserted
select @iscustom = '1'
insert into ptzaozhuang.dbo.xz08 (ptzaozhuang.dbo.xz08.code,ptzaozhuang.dbo.xz08.code_name,ptzaozhuang.dbo.xz08.code_abr1
,ptzaozhuang.dbo.xz08.code_abr2,ptzaozhuang.dbo.xz08.code_level,ptzaozhuang.dbo.xz08.code_leaf
,ptzaozhuang.dbo.xz08.sup_code,ptzaozhuang.dbo.xz08.code_assist,ptzaozhuang.dbo.xz08.invalid,ptzaozhuang.dbo.xz08.code_aname,ptzaozhuang.dbo.xz08.start_date
,ptzaozhuang.dbo.xz08.stop_date,ptzaozhuang.dbo.xz08.iscustom) values(
@code,@code_name,@code_abr1,@code_abr2,@code_level,@code_leaf,@sup_code,@code_assist,@invalid,@code_aname,@start_date,@stop_date,@iscustom)
--end
go
create trigger update_organization --定義觸發器
on org_organization --作用在那個表
for update --行級觸發器
as
--begin
declare @code varchar(8)
declare @code_name varchar(80)
declare @code_abr1 varchar(80)
declare @code_abr2 varchar(80)
declare @code_level float(53)
declare @is_leaf char(1) --臨時字段 判斷轉換使用
declare @code_leaf char(1)
declare @sup_code varchar(8)
declare @code_assist varchar(10)
declare @invalid varchar(2)
declare @code_aname varchar(100)
declare @start_date varchar(8)
declare @stop_date varchar(8)
declare @iscustom char(1)
select @code = orgid from inserted
select @code_name = orgname from inserted
select @code_abr1 = @code_name
select @code_abr2 = @code_name
select @code_level = orglevel from inserted
select @is_leaf = isleaf from inserted
if @is_leaf<>'n' --判斷轉換
select @code_leaf = '1'
if @is_leaf<>'y'
select @code_leaf = '0'
select @sup_code = parentorgid from inserted --轉換
select @code_assist = '1'
select @invalid = '1'
select @code_aname = @code_name
select @start_date = startdate from inserted
select @stop_date = enddate from inserted
select @iscustom = '1'
update ptzaozhuang.dbo.xz08 set
ptzaozhuang.dbo.xz08.code_name=@code_name,ptzaozhuang.dbo.xz08.code_abr1=@code_abr1
,ptzaozhuang.dbo.xz08.code_abr2=@code_abr2,ptzaozhuang.dbo.xz08.code_level=@code_level,ptzaozhuang.dbo.xz08.code_leaf=@code_leaf
,ptzaozhuang.dbo.xz08.sup_code=@sup_code,ptzaozhuang.dbo.xz08.code_assist=@code_assist,ptzaozhuang.dbo.xz08.invalid=@invalid
,ptzaozhuang.dbo.xz08.code_aname=@code_aname,ptzaozhuang.dbo.xz08.start_date=@start_date,ptzaozhuang.dbo.xz08.stop_date=@stop_date
,ptzaozhuang.dbo.xz08.iscustom=@iscustom
where
ptzaozhuang.dbo.xz08.code=@code
--end
總結:insert基於inserted虛擬表,有數據庫提供(沒增加一條,會在虛擬表中保存一份);
delete基於deleted虛擬表;
update基於deleted和inserted,先刪除修改的記錄,再增加修改後的記錄,所以update觸發器可以基於insert觸發器編寫;
補充:
insert觸發器:當增加某個表記錄時,動態創建一個表;
use sgcadrept
go
create trigger save_employee --定義觸發器
on org_employee --作用在那個表
for insert --行級觸發器
as
--begin
declare @userid varchar(60)
declare @loginname varchar(60)
declare @username varchar(100)
declare @userpwd varchar(50)
declare @state char(1)
declare @logintime varchar(20)
declare @creator varchar(60)
declare @organid varchar(100)
declare @organ varchar(200)
declare @createsql varchar(200) --拼接創建動態表語句
declare @createkey varchar(100) --創建主建語句
select @userid = empid from inserted
select @loginname = userid from inserted
select @username = empname from inserted
select @userpwd = 'e67c10a4c8fbfc0c400e047bb9a056a1'
select @state = '1'
select @logintime = GETDATE()
select @creator = 'admin'
select @organid = orgid from inserted
select @organ = orgname from org_organization where orgid = @organid
set @createsql = 'CREATE TABLE [ptzaozhuang].[dbo].[A01_RST_'+@loginname+'] ([A0000] numeric(18) NOT NULL ,[ISVALID] int NOT NULL ,[SORTID] int NULL ,[A0201AA] varchar(68) NULL ,[A0215] varchar(4) NULL)'
set @createkey = 'ALTER TABLE [ptzaozhuang].[dbo].[A01_RST_'+@loginname+'] ADD PRIMARY KEY ([A0000], [ISVALID])'
insert into ptzaozhuang.dbo.p_user (ptzaozhuang.dbo.p_user.userid,ptzaozhuang.dbo.p_user.loginname,ptzaozhuang.dbo.p_user.username
,ptzaozhuang.dbo.p_user.userpwd,ptzaozhuang.dbo.p_user.state,ptzaozhuang.dbo.p_user.logintime
,ptzaozhuang.dbo.p_user.creator,ptzaozhuang.dbo.p_user.organid,ptzaozhuang.dbo.p_user.organ) values(
@userid,@loginname,@username,@userpwd,@state,@logintime,@creator,@organid,@organ)
exec (@createsql) --執行創建表
exec (@createkey)
--end