關於SQLServer2000中觸發器的使用——多行資料提交
關於觸發器的使用,有很多爭議。
觸發器的好處不言而喻是增強了資料的校驗能力,能夠有效地實現複雜的業務邏輯。在一定程度上走的比約束和check走的更遠。
關於觸發器的壞處,最典型的就是觸發器的使用會導致系統效能下降,資料的不可控性,尤其是跨表檢測,以及可能導致的觸發器遞迴更加加深了資料的維護難度和不可控性。
本文無意討論觸發器的原理和好壞,旨在描述一個關於批次資料提交時的觸發器是如何設計的。
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE TRIGGER [TRI_xxx] ON xxx
FOR INSERT,UPDATE
AS
SET NOCOUNT ON
DECLARE
--檢測標誌設定
@CHECK INT,
--定義公共變數
@TODAY DATETIME
--定義基表變數
@field1 INT,
@field2 INT,
@field3 VARCHAR(20),
@fieldN INT,
--定義跨表變數
@table1_field1 INT,
@table1_field2 INT,
@tableN_fieldM INT
--定義遊標
DECLARE cur_xxx CURSOR FOR
SELECT field1,field2,field3,fieldN FROM INSERTED
--如果非集合修改,則定義為如下
/*
SELECT @field1=field1,
@field2=field2,
@field3=field3,
@field4=field4,
FROM INSERTED
*/
SET @TODAY=CONVERT(VARCHAR(10),GETDATE(),120)
OPEN CUR_ZYGD
FETCH NEXT FROM cur_xxx INTO @field1,@field2,@field3,@fieldN
WHILE (@@FETCH_STATUS=0)
BEGIN
------------------------------------------------------------------------
--------------------以下針對不同的規則,進行相關處理--------------------
------------------------------------------------------------------------
--滿足某某條件,則不處理直接退出
IF cond1
BEGIN
CLOSE cur_xxx --非遊標,無需該語句
DEALLOCATE cur_xxx --非遊標,無需該語句
RETURN
END
--滿足某某條件,則提示處理直接退出
IF cond2
BEGIN
RAISERROR('XXX錯誤!',16,1)
ROLLBACK TRAN
CLOSE cur_xxx --非遊標,無需該語句
DEALLOCATE cur_xxx --非遊標,無需該語句
RETURN
END
--跨表檢查,滿足某某條件,則提示處理直接退出
SELECT TOP 1 @table1_field1=field1 FROM table1 WHERE 1=1
IF cond3 IS NOT NULL
BEGIN
RAISERROR('XXX錯誤!',16,1)
ROLLBACK TRAN
CLOSE cur_xxx --非遊標,無需該語句
DEALLOCATE cur_xxx --非遊標,無需該語句
RETURN
ELSE
BEGIN
SET @field1=@table1_field1 --可能會根據其他跨表的結果更新當前值
END
--最後根據主鍵更新相關值
UPDATE xxx
SET field1=@field1,
field2=@field2
WHERE PrimaryKey=@PrimaryKey AND (ISNULL(field1,'')<>ISNULL(@field1,'') OR ISNULL(field2,0)<>ISNULL(@field2,0))
FETCH NEXT FROM cur_xxx INTO @field1,@field2,@field3,@fieldN
END
CLOSE CUR_xxx
DEALLOCATE CUR_xxx
SET NOCOUNT OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
觸發器的好處不言而喻是增強了資料的校驗能力,能夠有效地實現複雜的業務邏輯。在一定程度上走的比約束和check走的更遠。
關於觸發器的壞處,最典型的就是觸發器的使用會導致系統效能下降,資料的不可控性,尤其是跨表檢測,以及可能導致的觸發器遞迴更加加深了資料的維護難度和不可控性。
本文無意討論觸發器的原理和好壞,旨在描述一個關於批次資料提交時的觸發器是如何設計的。
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
CREATE TRIGGER [TRI_xxx] ON xxx
FOR INSERT,UPDATE
AS
SET NOCOUNT ON
DECLARE
--檢測標誌設定
@CHECK INT,
--定義公共變數
@TODAY DATETIME
--定義基表變數
@field1 INT,
@field2 INT,
@field3 VARCHAR(20),
@fieldN INT,
--定義跨表變數
@table1_field1 INT,
@table1_field2 INT,
@tableN_fieldM INT
--定義遊標
DECLARE cur_xxx CURSOR FOR
SELECT field1,field2,field3,fieldN FROM INSERTED
--如果非集合修改,則定義為如下
/*
SELECT @field1=field1,
@field2=field2,
@field3=field3,
@field4=field4,
FROM INSERTED
*/
SET @TODAY=CONVERT(VARCHAR(10),GETDATE(),120)
OPEN CUR_ZYGD
FETCH NEXT FROM cur_xxx INTO @field1,@field2,@field3,@fieldN
WHILE (@@FETCH_STATUS=0)
BEGIN
------------------------------------------------------------------------
--------------------以下針對不同的規則,進行相關處理--------------------
------------------------------------------------------------------------
--滿足某某條件,則不處理直接退出
IF cond1
BEGIN
CLOSE cur_xxx --非遊標,無需該語句
DEALLOCATE cur_xxx --非遊標,無需該語句
RETURN
END
--滿足某某條件,則提示處理直接退出
IF cond2
BEGIN
RAISERROR('XXX錯誤!',16,1)
ROLLBACK TRAN
CLOSE cur_xxx --非遊標,無需該語句
DEALLOCATE cur_xxx --非遊標,無需該語句
RETURN
END
--跨表檢查,滿足某某條件,則提示處理直接退出
SELECT TOP 1 @table1_field1=field1 FROM table1 WHERE 1=1
IF cond3 IS NOT NULL
BEGIN
RAISERROR('XXX錯誤!',16,1)
ROLLBACK TRAN
CLOSE cur_xxx --非遊標,無需該語句
DEALLOCATE cur_xxx --非遊標,無需該語句
RETURN
ELSE
BEGIN
SET @field1=@table1_field1 --可能會根據其他跨表的結果更新當前值
END
--最後根據主鍵更新相關值
UPDATE xxx
SET field1=@field1,
field2=@field2
WHERE PrimaryKey=@PrimaryKey AND (ISNULL(field1,'')<>ISNULL(@field1,'') OR ISNULL(field2,0)<>ISNULL(@field2,0))
FETCH NEXT FROM cur_xxx INTO @field1,@field2,@field3,@fieldN
END
CLOSE CUR_xxx
DEALLOCATE CUR_xxx
SET NOCOUNT OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-620586/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料庫的觸發器的使用資料庫觸發器
- 關於SQL SERVER觸發器的理解SQLServer觸發器
- 關於sqlserver2000的 jdbcSQLServerJDBC
- 關於主外來鍵表資料提交過程中的一點疑惑
- oracle 觸發器實現禁止在資料庫中建立dblink ---透過觸發器實現Oracle觸發器資料庫
- Oracle資料庫DDL審計觸發器觸發的bug問題Oracle資料庫觸發器
- sql觸發器刪除資料庫中的級聯記錄SQL觸發器資料庫
- (15)mysql 中的觸發器MySql觸發器
- 資料庫開發---常用物件-觸發器資料庫物件觸發器
- MySQL使用觸發器MySql觸發器
- 關於ORACLE 和MYSQL INNODB 觸發髒資料寫的機制對比OracleMySql
- 資料庫觸發器,禁止DDL操作資料庫觸發器
- SQL資料庫觸發器例項SQL資料庫觸發器
- 資料庫檢視,索引,觸發器資料庫索引觸發器
- 瞭解SQL Server觸發器及觸發器中的事務AWSQLServer觸發器
- SQL Sever 2000中的前觸發器和後觸發器SQL觸發器
- 依據前後資料關聯關係,生成多行資料
- 觸發器中操作LOB觸發器
- 關於order by中的資料排序排序
- 關於iOS開發中copy的使用iOS
- SqlServer觸發器的建立與使用SQLServer觸發器
- MySQL觸發器的使用規則MySql觸發器
- SQL Server資料庫級別觸發器SQLServer資料庫觸發器
- BEFORE觸發器修正資料錯誤觸發器
- ASP.NET DataGrid的多行提交ASP.NET
- Oracle 跨使用者表間資料操作(觸發器實現)Oracle觸發器
- 用觸發器記錄資料庫使用者登陸資訊觸發器資料庫
- SAP 資料更新的觸發
- mysql主從和觸發器的關係MySql觸發器
- Oracle中觸發器的應用 (zt)Oracle觸發器
- 觸發器中不能commit觸發器MIT
- 淺談SQL Server觸發器的使用SQLServer觸發器
- Oracle Instead of 觸發器的使用Oracle觸發器
- 觸發器實現表資料自動更新觸發器
- 審計資料庫登陸登出觸發器資料庫觸發器
- ORACLE表資料觸發器,僅保留一天的實時資料Oracle觸發器
- 【iCore4 雙核心板_FPGA】例程六:觸發器實驗——觸發器的使用FPGA觸發器
- 【iCore3 雙核心板_FPGA】例程八:觸發器實驗——觸發器的使用FPGA觸發器