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个固定的值到无关紧要的字段,确定有没有写错,不过一般语法错误都会构建失败的啦

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