如何编写INSTEAD OF触发器实现向视图中插入数据?
触发器错误原因
你当前编写的触发器存在两个核心问题:
- 递归调用错误:触发器内部直接向目标视图
[dbo].[VW_REX_EMPLOYEES]执行插入操作,会再次触发该INSTEAD OF触发器,形成无限递归,最终触发数据库递归层数限制报错。 - 逻辑错误:INSTEAD OF触发器的作用是替代视图本身的默认插入逻辑,你需要将插入目标改为视图依赖的物理基表,而非视图本身。
正确触发器编写示例
你的视图由两个基表XXX1AMTRESSXX.TRESS_SANM.dbo.Rex_Employees、SolutionsWebApp.dbo.Tbl_Non_TRESS_EMPLOYEES通过UNION ALL拼接而成,你需要根据业务规则判断插入的数据要写入哪张基表,以下是插入到第一张基表的示例:
ALTER TRIGGER [dbo].[AddEmployeeTrigger] on [dbo].[VW_REX_EMPLOYEES] INSTEAD OF INSERT AS BEGIN SET NOCOUNT ON; -- 插入到视图依赖的基表,排除视图的派生计算字段 INSERT INTO [XXX1AMTRESSXX.TRESS_SANM.dbo].[Rex_Employees] ([Company] ,[EmployeeID] ,[Emp_Status] ,[Emp_LastName1] ,[Emp_LastName2] ,[Emp_FirstNames] ,[Emp_FullName] -- 基表原始字段,视图会自动调用InitCap做转换 ,[Puesto] ,[Emp_Email] ,[Emp_SegSoc] ,[Emp_BornDate] ,[Emp_Hire_Date] ,[Emp_Entry_Date] ,[Emp_Type] ,[Emp_Gender] ,[Lab_Type] ,[Emp_Department] ,[VS] ,[Sup_ID] ,[Sup_Name] ,[Mgr_ID] ,[Mgr_Name] ,[Cost_Center] ,[CC_Description] ,[Emp_Shift_ID] ,[Mon_Shift] ,[Tue_Shift] ,[Wed_Shift] ,[Thu_Shift] ,[Fri_Shift] ,[Sat_Shift] ,[Sun_Shift] ,[TU_TIP_1] ,[TU_TIP_2] ,[TU_TIP_3] ,[TU_TIP_4] ,[TU_TIP_5] ,[TU_TIP_6] ,[TU_TIP_7] ,[PERSONAL_EMAIL] ,[SANMINA_EMAIL]) -- 基表原始字段,视图会自动按CASE规则生成展示值 SELECT [Company] ,[EmployeeID] ,[Emp_Status] ,[Emp_LastName1] ,[Emp_LastName2] ,[Emp_FirstNames] ,[Emp_FullName] ,[Puesto] ,[Emp_Email] ,[Emp_SegSoc] ,[Emp_BornDate] ,[Emp_Hire_Date] ,[Emp_Entry_Date] ,[Emp_Type] ,[Emp_Gender] ,[Lab_Type] ,[Emp_Department] ,[VS] ,[Sup_ID] ,[Sup_Name] ,[Mgr_ID] ,[Mgr_Name] ,[Cost_Center] ,[CC_Description] ,[Emp_Shift_ID] ,[Mon_Shift] ,[Tue_Shift] ,[Wed_Shift] ,[Thu_Shift] ,[Fri_Shift] ,[Sat_Shift] ,[Sun_Shift] ,[TU_TIP_1] ,[TU_TIP_2] ,[TU_TIP_3] ,[TU_TIP_4] ,[TU_TIP_5] ,[TU_TIP_6] ,[TU_TIP_7] ,[PERSONAL_EMAIL] ,[SANMINA_EMAIL] FROM INSERTED -- 可在这里加过滤条件,筛选要写入当前基表的数据 WHERE Emp_Status = 'S'; -- 如果需要同时支持写入第二个基表,可再加INSERT语句,写入SolutionsWebApp.dbo.Tbl_Non_TRESS_EMPLOYEES -- INSERT INTO [SolutionsWebApp.dbo].[Tbl_Non_TRESS_EMPLOYEES] (...) -- SELECT ... FROM INSERTED WHERE (判断属于该表的业务条件) END;
注意事项
- 视图的派生字段
Emp_FullName(InitCap函数转换)、SANMINA_EMAIL(CASE逻辑生成)不需要手动计算,只要给基表写入原始值即可,视图查询时会自动按定义生成对应值。 - 视图自带过滤规则:仅展示
Emp_Status = 'S'的正式员工数据,且过滤掉EmployeeID = 005000170的记录,插入基表时要符合对应规则,否则插入后在视图中查询不到对应数据。
插入语句使用说明
触发器编写正确的前提下,完全可以直接使用普通的INSERT INTO语句向视图插入数据,不需要修改原有插入逻辑,触发器会自动将数据转发到对应基表。
内容的提问来源于stack exchange,提问作者Brandon Cortes
相关产品推荐
相关产品推荐

