<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Vincent217

      博客園 首頁 新隨筆 聯系 訂閱 管理
      SQL觸發器實例1
      
      定義: 何為觸發器?在SQL Server里面也就是對某一個表的一定的操作,觸發某種條件,從而執行的一段程序。觸發器是一個特殊的存儲過程。 
            常見的觸發器有三種:分別應用于Insert , Update , Delete 事件。 
      
            我為什么要使用觸發器?比如,這么兩個表: 
      
            Create Table Student(              --學生表 
              StudentID int primary key,       --學號 
              .... 
             ) 
      
            Create Table BorrowRecord(               --學生借書記錄表 
              BorrowRecord   int identity(1,1),       --流水號   
              StudentID      int ,                    --學號 
              BorrowDate     datetime,                --借出時間 
              ReturnDAte     Datetime,                --歸還時間 
              ... 
            ) 
      
           用到的功能有: 
              1.如果我更改了學生的學號,我希望他的借書記錄仍然與這個學生相關(也就是同時更改借書記錄表的學號); 
              2.如果該學生已經畢業,我希望刪除他的學號的同時,也刪除它的借書記錄。 
           等等。 
      
           這時候可以用到觸發器。對于1,創建一個Update觸發器: 
      
           Create Trigger truStudent 
             On Student                         --在Student表中創建觸發器 
             for Update                          --為什么事件觸發 
           As                                        --事件觸發后所要做的事情 
             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分別表示觸發事件的表“舊的一條記錄”和“新的一條記錄”。 
           一個數據庫系統中有兩個虛擬表用于存儲在表中記錄改動的信息,分別是: 
                                   虛擬表Inserted                     虛擬表Deleted 
      
      在表記錄新增時     存放新增的記錄                         不存儲記錄 
               修改時           存放用來更新的新記錄                   存放更新前的記錄 
               刪除時           不存儲記錄                             存放被刪除的記錄 
      
      
           一個Update 的過程可以看作為:生成新的記錄到Inserted表,復制舊的記錄到Deleted表,然后刪除Student記錄并寫入新紀錄。 
      
           對于2,創建一個Delete觸發器 
           Create trigger trdStudent 
             On Student 
             for Delete 
           As 
             Delete BorrowRecord 
               From BorrowRecord br , Delted d 
               Where br.StudentID=d.StudentID 
      
           從這兩個例子我們可以看到了觸發器的關鍵:A.2個臨時的表;B.觸發機制。 
      
      SQL觸發器實例2
      
      /* 
      建立虛擬測試環境,包含:表[卷煙庫存表],表[卷煙銷售表]。 
      請大家注意跟蹤這兩個表的數據,體會觸發器到底執行了什么業務邏輯,對數據有什么影響。 
      為了能更清晰的表述觸發器的作用,表結構存在數據冗余,且不符合第三范式,這里特此說明。 
      */ 
      USE Master 
      GO 
      
      IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’U’ AND NAME = ’卷煙庫存表’) 
      DROP TABLE 卷煙庫存表 
      GO 
      IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’U’ AND NAME = ’卷煙銷售表’) 
      DROP TABLE 卷煙銷售表 
      GO 
      
      --業務規則:銷售金額 = 銷售數量 * 銷售單價 業務規則。 
      
      CREATE TABLE 卷煙銷售表 
      ( 
      卷煙品牌 VARCHAR(40) PRIMARY KEY NOT NULL, 
      購貨商 VARCHAR(40) NULL, 
      銷售數量 INT NULL, 
      銷售單價 MONEY NULL, 
      銷售金額 MONEY NULL 
      ) 
      GO 
      
      --業務規則:庫存金額 = 庫存數量 * 庫存單價 業務規則。 
      
      CREATE TABLE 卷煙庫存表 
      ( 
      卷煙品牌 VARCHAR(40) PRIMARY KEY NOT NULL, 
      庫存數量 INT NULL, 
      庫存單價 MONEY NULL, 
      庫存金額 MONEY NULL 
      ) 
      GO 
      
      --創建觸發器,示例1 
      
      /* 
      創建觸發器[T_INSERT_卷煙庫存表],這個觸發器較簡單。 
      說明: 每當[卷煙庫存表]發生 INSERT 動作,則引發該觸發器。 
      觸發器功能: 強制執行業務規則,保證插入的數據中,庫存金額 = 庫存數量 * 庫存單價。 
      注意: [INSERTED]、[DELETED]為系統表,不可創建、修改、刪除,但可以調用。 
      重要: 這兩個系統表的結構同插入數據的表的結構。 
      */ 
      IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’TR’ AND NAME = ’T_INSERT_卷煙庫存表’) 
      DROP TRIGGER T_INSERT_卷煙庫存表 
      GO 
      
      CREATE TRIGGER T_INSERT_卷煙庫存表 
      ON 卷煙庫存表 
      FOR INSERT 
      AS 
      --提交事務處理 
      BEGIN TRANSACTION 
      --強制執行下列語句,保證業務規則 
      UPDATE 卷煙庫存表 
      SET 庫存金額 = 庫存數量 * 庫存單價 
      WHERE 卷煙品牌 IN (SELECT 卷煙品牌 from INSERTED) 
      COMMIT TRANSACTION 
      GO 
      
      /* 
      針對[卷煙庫存表],插入測試數據: 
      注意,第一條數據(紅塔山新勢力)中的數據符合業務規則, 
      第二條數據(紅塔山人為峰)中,[庫存金額]空,不符合業務規則, 
      第三條數據(云南映像)中,[庫存金額]不等于[庫存數量]乘以[庫存單價],不符合業務規則。 
      第四條數據庫存數量為0。 
      請注意在插入數據后,檢查[卷煙庫存表]中的數據是否 庫存金額 = 庫存數量 * 庫存單價。 
      */ 
      
      INSERT INTO 卷煙庫存表(卷煙品牌,庫存數量,庫存單價,庫存金額) 
      SELECT ’紅塔山新勢力’,100,12,1200 UNION ALL 
      SELECT ’紅塔山人為峰’,100,22,NULL UNION ALL 
      SELECT ’云南映像’,100,60,500 UNION ALL 
      SELECT ’玉溪’,0,30,0 
      GO 
      
      --查詢數據 
      
      SELECT * FROM 卷煙庫存表 
      GO 
      /* 
      
      結果集 
      
      RecordId 卷煙品牌 庫存數量 庫存單價 庫存金額 
      -------- ------------ -------- ------- --------- 
      1 紅塔山新勢力 100 12.0000 1200.0000 
      2 紅塔山人為峰 100 22.0000 2200.0000 
      3 云南映像 100 60.0000 6000.0000 
      4 玉溪 0 30.0000 .0000 
      
      (所影響的行數為 4 行) 
      
      */ 
      
      --觸發器示例2 
      
      /* 
      創建觸發器[T_INSERT_卷煙銷售表],該觸發器較復雜。 
      說明: 每當[卷煙庫存表]發生 INSERT 動作,則引發該觸發器。 
      觸發器功能: 實現業務規則。 
      業務規則: 如果銷售的卷煙品牌不存在庫存或者庫存為零,則返回錯誤。 
      否則則自動減少[卷煙庫存表]中對應品牌卷煙的庫存數量和庫存金額。 
      */ 
      IF EXISTS (SELECT NAME FROM SYSOBJECTS WHERE XTYPE = ’TR’ AND NAME = ’T_INSERT_卷煙銷售表’) 
      DROP TRIGGER T_INSERT_卷煙銷售表 
      GO 
      
      CREATE TRIGGER T_INSERT_卷煙銷售表 
      ON 卷煙銷售表 
      FOR INSERT 
      AS 
      BEGIN TRANSACTION 
      --檢查數據的合法性:銷售的卷煙是否有庫存,或者庫存是否大于零 
      IF NOT EXISTS ( 
      SELECT 庫存數量 
      FROM 卷煙庫存表 
      WHERE 卷煙品牌 IN (SELECT 卷煙品牌 FROM INSERTED) 
      ) 
      BEGIN 
      --返回錯誤提示 
      RAISERROR(’錯誤!該卷煙不存在庫存,不能銷售。’,16,1) 
      --回滾事務 
      ROLLBACK 
      RETURN 
      END 
      
      IF EXISTS ( 
      SELECT 庫存數量 
      FROM 卷煙庫存表 
      WHERE 卷煙品牌 IN (SELECT 卷煙品牌 FROM INSERTED) AND 
      庫存數量 <= 0 
      ) 
      BEGIN 
      --返回錯誤提示 
      RAISERROR(’錯誤!該卷煙庫存小于等于0,不能銷售。’,16,1) 
      --回滾事務 
      ROLLBACK 
      RETURN 
      END 
      
      --對合法的數據進行處理 
      
      --強制執行下列語句,保證業務規則 
      UPDATE 卷煙銷售表 
      SET 銷售金額 = 銷售數量 * 銷售單價 
      WHERE 卷煙品牌 IN (SELECT 卷煙品牌 FROM INSERTED) 
      
      DECLARE @卷煙品牌 VARCHAR(40) 
      SET @卷煙品牌 = (SELECT 卷煙品牌 FROM INSERTED) 
      
      DECLARE @銷售數量 MONEY 
      SET @銷售數量 = (SELECT 銷售數量 FROM INSERTED) 
      
      UPDATE 卷煙庫存表 
      SET 庫存數量 = 庫存數量 - @銷售數量, 
      庫存金額 = (庫存數量 - @銷售數量)*庫存單價 
      WHERE 卷煙品牌 = @卷煙品牌 
      COMMIT TRANSACTION 
      GO 
      
      --請大家自行跟蹤[卷煙庫存表]和[卷煙銷售表]的數據變化。 
      --針對[卷煙銷售表],插入第一條測試數據,該數據是正常的。 
      
      INSERT INTO 卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額) 
      SELECT ’紅塔山新勢力’,’某購貨商’,10,12,1200 
      GO 
      
      --針對[卷煙銷售表],插入第二條測試數據,該數據 銷售金額 不等于 銷售單價 * 銷售數量。 
      --觸發器將自動更正數據,使 銷售金額 等于 銷售單價 * 銷售數量。 
      
      INSERT INTO 卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額) 
      SELECT ’紅塔山人為峰’,’某購貨商’,10,22,2000 
      GO 
      
      --針對[卷煙銷售表],插入第三條測試數據,該數據中的卷煙品牌在 卷煙庫存表中找不到對應。 
      --觸發器將報錯。 
      
      INSERT INTO 卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額) 
      SELECT ’紅河V8’,’某購貨商’,10,60,600 
      GO 
      
      /* 
      結果集 
      服務器: 消息 50000,級別 16,狀態 1,過程 T_INSERT_卷煙銷售表,行 15 
      錯誤!該卷煙不存在庫存,不能銷售。 
      */ 
      
      --針對[卷煙銷售表],插入第三條測試數據,該數據中的卷煙品牌在 卷煙庫存表中庫存為0。 
      --觸發器將報錯。 
      
      INSERT INTO 卷煙銷售表(卷煙品牌,購貨商,銷售數量,銷售單價,銷售金額) 
      SELECT ’玉溪’,’某購貨商’,10,30,300 
      GO 
      
      /* 
      結果集 
      服務器: 消息 50000,級別 16,狀態 1,過程 T_INSERT_卷煙銷售表,行 29 
      錯誤!該卷煙庫存小于等于0,不能銷售。 
      */ 
      --查詢數據 
      SELECT * FROM 卷煙庫存表 
      
      SELECT * FROM 卷煙銷售表 
      GO 
      
      /* 
      補充: 
      1、本示例主要通過一個簡單的業務規則實現來進行觸發器使用的說明,具體的要根據需要靈活處理; 
      2、關于觸發器要理解并運用好 INSERTED ,DELETED 兩個系統表; 
      3、本示例創建的觸發器都是 FOR INSERT ,具體的語法可參考: 
      /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                                                            Trigger語法
      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      
      
      CREATE TRIGGER trigger_name 
      ON { table | view } 
      [ WITH ENCRYPTION ] --用于加密觸發器 
      { 
      { { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ , ] [ UPDATE ] } 
      [ WITH APPEND ] 
      [ NOT FOR REPLICATION ] 
      AS 
      [ { IF UPDATE ( column ) 
      [ { AND | OR } UPDATE ( column ) ] 
      [ ...n ] 
      | IF ( COLUMNS_UPDATED ( ) { bitwise_operator } updated_bitmask ) 
      { comparison_operator } column_bitmask [ ...n ] 
      } ] 
      sql_statement [ ...n ] 
      } 
      } 
      
      4、關于觸發器,還應該注意 
      (1)、DELETE 觸發器不能捕獲 TRUNCATE TABLE 語句。 
      (2)、觸發器中不允許以下 Transact-SQL 語句: 
      ALTER DATABASE CREATE DATABASE DISK INIT 
      DISK RESIZE DROP DATABASE LOAD DATABASE 
      LOAD LOG RECONFIGURE RESTORE DATABASE 
      RESTORE LOG 
      (3)、觸發器最多可以嵌套 32 層。 
      
      */ 
      
      --修改觸發器 
      --實質上,是將 CREATE TRIGGER ... 修改為 ALTER TRIGGER ...即可。 
      
      --刪除觸發器 
      DROP TRIGGER xxx 
      GO 
      
      --刪除測試環境 
      DROP TABLE 卷煙庫存表 
      GO 
      DROP TABLE 卷煙銷售表 
      GO 
      DROP TRIGGER T_INSERT_卷煙庫存表 
      GO 
      DROP TRIGGER T_INSERT_卷煙銷售表 
      GO 
      ################################################################## 
      觸發器的基礎知識和例子 
      :create trigger tr_name 
      on table/view 
      {for | after | instead of } [update][,][insert][,][delete] 
      [with encryption] 
      as {batch | if update (col_name) [{and|or} update (col_name)] } 
      
      說明: 
      1 tr_name :觸發器名稱 
      2 on table/view :觸發器所作用的表。一個觸發器只能作用于一個表 
      3 for 和after :同義 
      4 after 與instead of :sql 2000新增項目afrer 與 instead of 的區別 
      After 
      在觸發事件發生以后才被激活,只可以建立在表上 
      Instead of 
      代替了相應的觸發事件而被執行,既可以建立在表上也可以建立在視圖上 
      5 insert、update、delete:激活觸發器的三種操作,可以同時執行,也可選其一 
      6 if update (col_name):表明所作的操作對指定列是否有影響,有影響,則激活觸發器。此外,因為delete 操作只對行有影響, 
      所以如果使用delete操作就不能用這條語句了(雖然使用也不出錯,但是不能激活觸發器,沒意義)。 
      7 觸發器執行時用到的兩個特殊表:deleted ,inserted 
      deleted 和inserted 可以說是一種特殊的臨時表,是在進行激活觸發器時由系統自動生成的,其結構與觸發器作用的表結構是一 
      樣的,只是存放 的數據有差異。 
      
      續 
      下面表格說明deleted 與inserted 數據的差異 
      deleted 與inserted 數據的差異 
      Inserted 
      存放進行insert和update 操作后的數據 
      Deleted 
      存放進行delete 和update操作前的數據 
      注意:update 操作相當于先進行delete 再進行insert ,所以在進行update操作時,修改前的數據拷貝一條到deleted 表中,修改后 
      的數據在存到觸發器作用的表的同時,也同時生成一條拷貝到insered表中
      /////////
      CREATE TRIGGER [TRIGGER admixture_receive_log] ON dbo.chl_lydj 
      FOR UPDATE
      AS
      begin
              declare @djsfxg char(10)      declare @wtbh char(20)
              select @wtbh=wtbh from inserted
             update ly_tzk set djsfxg='已修改' where wtbh=@wtbh
      end
      if (select data_sfjl from t_logsetup)='是'
      begin
      declare @oldcjmc char (100)          declare @oldlyrq datetime
      declare @oldbzbh char (60)             declare @oldzl char (20)
      declare @olddj char (10)
      declare @newcjmc char (100)          declare @newlyrq datetime
      declare @newbzbh char (60)             declare @newzl char (20)
      declare @newdj char (10)
                   declare @xgr char (20)
                   select @oldcjmc=cjmc,@oldlyrq=lyrq,@oldbzbh=bzbh,@oldzl=zl,@olddj=dj from deleted
                   select @newcjmc=cjmc,@newlyrq=lyrq,@newbzbh=bzbh,@newzl=zl,@newdj=dj from inserted
                   select @xgr=xgr from t_modifyuser where @wtbh=wtbh
                   
               if @oldcjmc<>@newcjmc
                   begin
                            insert into t_modifylog (wtbh, mod_time, mod_table, mod_field, ori_value, now_value, mod_people) values
                            (@wtbh,getdate(), 'chl_lydj','cjmc', @oldcjmc, @newcjmc, @xgr)
                   end
      
      end
      //////////修改時,直接把‘create’改為‘alter’即可
      /////////////////////////
      CREATE TRIGGER [TRIGGER ly_tzk_syf] ON dbo.ly_tzk 
      FOR insert 
      AS
      begin
               declare @clmc char(100)     declare @dwbh char(100) declare @syf char(100)   declare @dwgcbh char(100) declare @wtbh char(50) 
               declare @dj_1 money     declare @feiyong_z money   declare @feiyong_xf money   declare @feiyong_sy money 
               declare @dj char(20)
              select @wtbh=wtbh , @clmc=clmc , @dwbh=dwbh ,@syf=syf from inserted
              select   @dj=dj from feihao_bz where clmc=@clmc
              select @feiyong_z=feiyong_z, @feiyong_xf=feiyong_xf, @feiyong_sy=feiyong_sy from gongchengxinxi where dwgcbh=@dwbh
              set @dj_1=convert(money ,@dj)
             if @dj_1 <>0 
             begin
                   set @feiyong_xf=@feiyong_xf+@dj_1
                   set @feiyong_sy=@feiyong_sy-@dj_1
              
                  update ly_tzk set syf=@dj where wtbh=@wtbh      
                  update gongchengxinxi set feiyong_xf=@feiyong_xf, feiyong_sy=@feiyong_sy where dwgcbh=@dwbh 
             end
             else    update ly_tzk set syf=convert(char , 0.0) where wtbh=@wtbh
      end
      //////////////////////
      CREATE TRIGGER [TRIGGER ly_tzk_syf_shanchu] ON dbo.ly_tzk 
      FOR delete 
      AS
      begin
               declare @clmc char(100)     declare @dwbh char(100)    declare @dwgcbh char(100) declare @wtbh char(50) 
               declare @feiyong_z money    declare @feiyong_xf money   declare @feiyong_sy money 
               declare @syf char(100)      declare @syf_1 money
               --declare @dj char(20)   declare @dj_1 money 
              select @wtbh=wtbh , @clmc=clmc , @dwbh=dwbh ,@syf=syf from inserted
              --select   @dj=dj from feihao_bz where clmc=@clmc
              select @feiyong_z=feiyong_z, @feiyong_xf=feiyong_xf, @feiyong_sy=feiyong_sy from gongchengxinxi where dwgcbh=@dwbh
              set @syf_1=convert(money ,@syf)
             if @syf_1 <>0 
             begin
                   set @feiyong_xf=@feiyong_xf-@syf_1
                   set @feiyong_sy=@feiyong_sy+@syf_1 
                  update gongchengxinxi set feiyong_xf=@feiyong_xf, feiyong_sy=@feiyong_sy where dwgcbh=@dwbh 
             end
      end
      //////////////////////

       

      來源:http://qsfwy.iteye.com/blog/424789

      posted on 2014-01-02 18:03  Vincent217  閱讀(203)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日本内射精品一区二区视频| 男女啪祼交视频| 18禁黄无遮挡网站免费| 久久午夜夜伦鲁鲁片免费无码| 亚洲av综合久久成人网| 欧美牲交videossexeso欧美| 亚洲av成人区国产精品| 鹤岗市| 国产亚洲一区二区三区av| 日日躁夜夜躁狠狠躁超碰97| 激情人妻自拍中文夜夜嗨| 四虎永久免费精品视频| 东方av四虎在线观看| 性色在线视频精品| 国内精品久久久久影院蜜芽| 亚洲大尺度一区二区av| AV秘 无码一区二| 一亚洲一区二区中文字幕| 丁香婷婷综合激情五月色| 精品国产午夜理论片不卡| 兴文县| h无码精品3d动漫在线观看| 少妇办公室好紧好爽再浪一点 | 曰韩亚洲AV人人夜夜澡人人爽| 男人猛戳女人30分钟视频大全| 国产精品亚洲а∨天堂2021 | 国产日韩精品中文字幕| 人人做人人澡人人人爽| 无码国产精品一区二区免费3p| 亚洲人成电影网站 久久影视| 丝袜美腿视频一区二区三区| 福利一区二区不卡国产| 色偷偷偷久久伊人大杳蕉| 日韩高清不卡免费一区二区| 极品白嫩少妇无套内谢| 亚洲香蕉免费有线视频| 精品偷拍被偷拍在线观看| 久久婷婷五月综合色国产免费观看| 国产最大的福利精品自拍| mm1313亚洲国产精品| 人妻少妇久久中文字幕|