SQLServer存儲過程/觸發器 Demo

需求

創建一個觸發器。插入student表一條數據,根據student的表字段teacher_name,去查詢teacher表,獲取teacher表字段的主鍵,然後重新更新到當前student表的teacher_id字段。

原本想要參考之前寫的mysql觸發器調用存儲過程的思路去弄的,然後查資料發現好像SQLServer不支持在觸發器調用存儲過程就放棄了。既然不能在觸發器裏面調用存儲過程,那就乾脆把存儲過程的sql也寫到觸發器了。

本文還是先從存儲過程編寫開始說起吧。

1. 存儲過程

按照需求,我的思路就是編寫一個存儲過程,入參是student的主鍵id,以及teacher_name,然後寫sql進行update,具體如下:

USE  dbo  -- 對應的數據庫
GO
	-- 創建存儲過程 sp_student  入參 p_teacher_name 和 p_id
	CREATE PROCEDURE 
		sp_student @p_teacher_name CHAR(20) , @p_id CHAR(20) 
	AS
		UPDATE 
			student s
		SET
			s.teacher_id = ( 
					SELECT
						t.id
					FROM
						teacher t
					WHERE
						t.teacher_name = @p_teacher_name 
			)
		WHERE
			s.id = @p_id

嘗試調用存儲過程

EXEC.dbo.sp_student @p_id =1 ,@p_teacher_name = '張三'  

如果調用存儲過程,你的student表teacher_id字段有關聯上,那就沒問題了。

2. 觸發器編寫

上網查資料說SQLServer是不允許在觸發器調用存儲過程的,具體我也沒去測試行不行,反正我就把上面的存儲過程改一下就好了。先貼SQL:

CREATE TRIGGER tri_insert ON student AFTER INSERT AS
IF
 EXISTS ( SELECT * FROM inserted ) 
 BEGIN
 
  -- 聲明變量,這裏注意 VARCHAR類型後面記得加上位數,不然默認好像是一位,這裏我踩過坑。
 DECLARE
  @teacher_name  VARCHAR(20),@teacher_id VARCHAR(20); 
  
-- SQLServer觸發器裏面,插入數據後,會把數據放到臨時表inserted裏面,所以我們只要在觸發器的sql裏面,從這個表裏面select你想要的字段,就可以拿到當前數據插入後對應字段的值了。

 SELECT
  @teacher_name  = teacher_name 
 FROM
  inserted;
  
  -- 根據剛從臨時表獲取的@teacher_name的值(即當前觸發器剛插入數據字段teacher_name字段的值)
  -- 查詢teacher表獲取id,並且賦給變量@teacher_id
 SELECT
  @teacher_id = id  
 FROM
	  teacher
 WHERE
	  teacher_name = @teacher_name;
	  
-- 根據id 直接更新teacher_id的值
 UPDATE 
 	student 
 SET 
 	teacher_id = @teacher_id 
 WHERE
  ID = ( SELECT id FROM inserted );  -- 直接定位到當前更新的數據

END

最後一點調試小技巧:
把變量的值set到無關緊要字段,來看看變量的值,是什麼,或者set個固定的值到無關緊要的字段,確定有沒有寫錯,不過一般語法錯誤都會構建失敗的啦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章