需求
創建一個觸發器。插入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個固定的值到無關緊要的字段,確定有沒有寫錯,不過一般語法錯誤都會構建失敗的啦