MS-SQL 要嗎就要小心寫trigger,不然的話就只開放stored procedure

摘要:MS-SQL 要嗎就要小心寫trigger,不然的話就只開放stored procedure

昨天在做測試的時候寫了一段觸發程序


/****** Object:  Trigger [empEpay]    Script Date: 12/02/2011 08:24:36 ******/
IF  EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[empxxx]'))
DROP TRIGGER [dbo].[empxxx]
GO

CREATE TRIGGER [dbo].[empxxx] 
   ON  [dbo].[employee]
   AFTER INSERT,UPDATE
AS 
BEGIN
	SET NOCOUNT ON;
        ---放你想做的事
		INSERT INTO [dbo].[test] ([a]) VALUES(CONVERT(VARCHAR(23), GETDATE(), 121))
       ---放你想做的事

END

GO

後做下面的test

Update employee

Set  欄位1=值1

       .....

where 更新條件

go

 

ok到這個階段是沒問題的

接下來開始本文

今天其實我測試的時候實驗10萬次都是正常的

但是其實上面的寫法是不對的....

做一個實驗


SELECT *
INTO emp2
FROM employee
go

然後

--  truncate table employee --<--這一行只是要把資料清掉,好孩子不要亂下 ,會死人的

把資料insert回去


insert into employee( 欄位....)
SELECT  欄位....
FROM dbo.emp2

ok慘劇發生了...
在上面的Triggle我是寫將操作時間寫入到db中
但是....db只發現一筆   <只有囧字一字可以形容>
當然...慘劇發生老闆一定會要求Solution
我現在的解法方法有2種
第一種....TRIGGER 不變
     .....那就寫預存程序+身分切換
     這個不是我這次的重點.老實說這是一個比較不負責任的寫法...意思指自己不動.叫所有前端程式用sp來存取Table...<--這應該會被抓去打屁屁

IF  EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[dbo].[empxxx]'))
DROP TRIGGER [dbo].[empxxx]
GO

CREATE TRIGGER [dbo].[empxxx] 
   ON  [dbo].[employee]
   AFTER INSERT,UPDATE
AS 
BEGIN
	SET NOCOUNT ON;
	
DECLARE my_Cursor CURSOR FAST_FORWARD FOR SELECT .... FROM INSERTED;

	OPEN my_Cursor 
	FETCH NEXT FROM my_Cursor into .....

	WHILE @@FETCH_STATUS = 0 
	BEGIN 
		INSERT INTO [dbo].[test] ([a]) VALUES(CONVERT(VARCHAR(23), GETDATE(), 121))

	FETCH NEXT FROM my_Cursor into ....  
	END

	CLOSE my_Cursor
	DEALLOCATE my_Cursor	
END

GO

...

這樣財部會又漏資料...

能寫出這篇心得感謝楊志強老師的解釋與指導....否則換我要去客戶解釋了....