首頁 > php教程 > PHP开发 > sql 觸發器操作詳解

sql 觸發器操作詳解

高洛峰
發布: 2016-12-14 16:28:08
原創
1543 人瀏覽過

觸發器對錶進行插入、更新、刪除的時候會自動執行的特殊預存程序。觸發器一般用在check約束更複雜的約束上面。觸發器和普通的預存程序的區別是:觸發器是當對某一個表進行操作時。諸如:update、insert、delete這些操作的時候,系統會自動呼叫執行該表上對應的觸發器。 SQL Server 2005中觸發器可以分為兩類:DML觸發器和DDL觸發器,其中DDL觸發器它們會影響多種資料定義語言語句而激發,這些語句有create、alter、drop語句。

常見的觸發器有三種:分別應用於Insert , Update , Delete 事件。

      我為什麼要使用觸發器?例如,如此兩張表:

  

    Create Table Student(              --        .... 
      )

      Create Table BorrowRecord(       BorrowRecord   int identity(1,1),       --流水號   

       ‧ StudentID             BorrowDate     datetime,                --有時間         --歸還時間 

        ... 
      )

     所使用的功能有: 
        1.如果我更改了學生的學號,我希望他的借書記錄仍然與這個學生相關(也就是同時更改借書記錄表的學號); 
        2.如果該學生已經畢業,我如果該學生已經畢業,我希望刪除他的學號的同時,也刪除它的借書紀錄。 
     等等。

     這時候可以用到觸發器。對於1,建立一個Update觸發器:

   

  Create Trigger truStudent 

       On Student      

       for Update                                                --所要做的事 

       if Update (StudentID)            

       begin


         Update BorrowRecord 
           Set StudentID=i.StudentID 
           From BorrowRecord br , Deleted   d ,Inserted i      --Deleted和Inserted臨時表 
           Where br.StudentID=d.StudentID

       end        

                


     理解觸發器裡面的兩個臨時的表:Deleted , Inserted 。注意Deleted 與Inserted分別表示觸發事件的表格「舊的一筆記錄」與「新的一筆記錄」。
     一個資料庫教學系統中有兩個虛擬表用於儲存表中記錄變更的資訊,分別是: 
                            虛擬表Deleted

在表記錄新增時     儲存新增的記錄             修改時           存放用來更新的新紀錄                                                 儲存刪除的記錄

 ,然後刪除Student記錄並寫入新紀錄。


 

    2,創建一個Delete觸發器 

     Create trigger trdStudent 

           Delete BorrowRecord 
         From BorrowRecord br , Delted d 
        個例子我們可以看到了觸發器的關鍵:A.2個臨時的表;B.觸發機制

    DML觸發器分為:

    1、after觸發器(之後觸發)

    1、after觸發器(之後觸發)

   

        b、 update觸發器

        c、 delete觸發器

 

只有執行某一操作insert、update、delete之後觸發器才被觸發,只能定義在表上。而instead of觸發器表示並不執行其定義的操作(insert、update、delete)而僅是執行觸發器本身。既可以在表上定義instead of觸發器,也可以在視圖上定義。

 

    觸發器有兩個特殊的表:插入表(instered表)和刪除表(deleted表)。這兩張是邏輯表也是虛表。有系統在記憶體中創建者兩張表,不會儲存在資料庫中。而且兩張表的都是唯讀的,只能讀取資料而不能修改資料。這兩張表的結果總是與被改觸發器所應用的表的結構相同。當觸發器完成工作後,這兩張表就會被刪除。 Inserted表的數據是插入或是修改後的數據,而deleted表的數據是更新前的或是刪除的數據。

    Update資料的時候就是先刪除表格記錄,然後再增加一筆記錄。這樣在inserted和deleted表就都有update後的資料記錄了。注意的是:觸發器本身就是一個事務,所以在觸發器裡面可以對修改資料進行一些特殊的檢查。如果不滿足可以利用交易回滾,撤銷操作。

 

Ø 建立觸發器

 

   語法

create trigger tgr_nameinstead of 触发器 on table_name

with encrypion – 觸發

    # 建立insert類型觸發器

--建立insert插入類型觸發器
if (object_id('tgr_classes_insert', 'tr') is not null)
   drop trigger tgr_classes_insert
go
create trigger tgr_class_class_classes_insert
   - -定義變數
   declare @id int, @name varchar(20), @temp int;
   --在inserted表中查詢已插入記錄資訊
   select @id = id, @name = name from fromtedname; = @name + convert(varchar, @id);
   set @temp = @id / 2;    
   insert into student values(@name, 18 + @id, @temp, @id); ';
go
--插入資料
insert into classes values('5班', getDate());
--查詢資料
select * from classes;
select * from student order by id;
🠎ins ,會在inserted表中新增一筆剛插入的記錄。

 

    # 建立delete型別觸發器

--delete刪除型別觸發器

if (object_id('tgr_classes_delete', 'cate es_delete

on classes

for delete --刪除觸發

as

   print '備份資料中…';    

   if (object_id('classesBackup', 'U') is not null)
   Backup select name , createDate from deleted;
   else
       --不存在classesBackup建立再插入
       select * into classesBackup from deleted;🎠備份資料成功! ';
go
--
--不顯示影響行數
--set nocount on;
delete classes where name = '5班';
--查詢資料
select * from classes;
select * from classesB--查詢資料
select * from classes;
seackup;

   delete觸發器會在刪除資料的時候,將剛才刪除的資料保存在deleted表中。

 

    # 建立update型別觸發器

--update更新型別觸發器
if (object_id('tgr_classes_update', 'TR') is not nullrigdate gr tgr_classes_update

on classes

for update

as

   declare @oldName varchar(20), @newName varchar(20);

   --更新前的資料

   select @oldName = name from deleted; '+ @oldName + '%'))

       begin

           --更新後的資料
         = replace(name, @oldName, @newName) where name like '%' + @oldName + '%';
           print '級聯修改資料成功! ';
       end
   else
       print '無修改student手錶! ';
go
--查詢資料
select * from student order by id;
select * from classes;
update classes set name = '五班' where name = '5班';資料後,將更新前的資料保存在inserted表中,更新後的資料保存在inserted表中。

 

    # update更新列級觸發器

if (object_id('tgr_classes_update_column', 'TR') is not null)
classes_update_column
on classes
   for update
as
   --列級觸發器:是否更新了班級創建時間
   if (update(createDate))
   begin
       raisError('系統提示:

go

--測試

select * from student order by id;

select * from classes;

update classes set createDate = getDate() where id = 3;

update classes set name = '四班';列級觸發器可以用update是否判斷更新列記錄;

 

    # instead of類型觸發器

       instead of觸發器表示不執行其定義的操作僅是執行其定義的操作(insert、update、delete.本身的內容。

       建立文法

create trigger tgr_name
on table_name
with encryption
   instead of update...
as
   T-SQL

id('tgr_classes_inteadOf', 'TR') is not null )

   drop trigger tgr_classes_inteadOf

go

create trigger tgr_classes_inteadOf

on classes

   instead of delete/*, update, classes
   instead of delete/*, update, 類
   --查詢被刪除的信息,病賦值
   select @id = id, @name = name from deleted;
   print 'id: ' + convert(varchar, @id) + ', name: ' + @name;
   --先刪除student的資訊
ete  student where cid = @id;
   --再刪除classes的訊息
   delete classes where id = @id;
   print '刪除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的訊息成功! ';
go
--test
select * from student order by id;
select * from classes;
delete classes where id = 7;

   
_rao🠎ion sage' , 'TR') is not null)
   drop trigger tgr_message
go
create trigger tgr_message

on student

   after insert, update

on student

   after insert, update

, 11,005,000,000 messmdate

', 1,005,000mess);
--test
insert into student values('lily', 22, 1, 7);
update student set sex = 0 where name = 'lucy';
select * from student order by id;

夾修改器修改器tgr_message
on student
after delete
as raisError('tgr_message觸發器被觸發', 16, 10);
go
--test

delete from student where name = 'go

--test

delete from student where name = 'go

--test
delete from student where name = '';啟用器
--停用觸發器
disable trigger tgr_message on student;
--啟用觸發器
enable trigger tgr_message on student;

    # 查詢所建立的觸發器資訊

. .triggers;

select * from sys.objects where type = 'TR';


--查看觸發器觸發事件
select te.* from sys.trigger_events te join sys.triggers t
on t.object_object.

where t.parent_class = 0 and t.name = 'tgr_valid_data';

--查看創建觸發器語句

exec sp_helptext 'tgr_message';
tgr_valid_data', 'TR') is not null))
   drop trigger tgr_valid_data
go
create trigger tgr_valid_data
on student
 @name varchar(20);
   select @name = s .name, @age = s.age from inserted s;
   if (@age    begin
       raisError('為插入新資料的age

go

--test

insert into student values('forest', 2, 0, 7);

insert into student values('forest', 22, 0, 7);

select * from student order by id;🎠 範例,作業日誌


if (object_id('log', 'U') is not null)
   drop table log
go
create table log(
  id int identity
create table log(
  id int identity(1, 1) ,
   createDate datetime default getDate()
)
go
if (exists (select * from sys.objects where name = 'tgr_student_log'))
名詞
on student
after insert, update, delete
as
   if ((exists (select 1 from inserted)) and (exists (select 1 from deleted)))
   begin
      insert in log(action) value se if (exists ( select 1 from inserted) and not exists (select 1 from deleted))
   begin

       insert into log(action) values('inserted');🠦 (select 1 from deleted))

   begin

       insert into log(action) values('deleted');

   end
go
--test
insert into student values('king', 22, 1, 7);
update student set sex = 0 where name = 'king';
delete student where name = 'king';
select * from log;
select * from student order by id;



相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門推薦
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板