如何使用 INSTEAD OF 触发器在视图中插入数据?

Posted

技术标签:

【中文标题】如何使用 INSTEAD OF 触发器在视图中插入数据?【英文标题】:How do I insert data in a view using INSTEAD OF trigger? 【发布时间】:2021-11-08 23:16:09 【问题描述】:

我试图在视图中插入一些数据,但是,我收到的错误基本上告诉我,由于常量或派生字段,我不能这样做。但无论如何,我做了一些研究,发现我必须使用 INSTEAD OF 才能将数据插入到视图中。

所以我的问题是编写此触发器的正确​​方法是什么?这就是我所拥有的:

ALTER TRIGGER [dbo].[AddEmployeeTrigger] on [dbo].[VW_REX_EMPLOYEES]
INSTEAD OF INSERT
AS
BEGIN

  INSERT INTO [dbo].[VW_REX_EMPLOYEES]
       ([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])
     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;
END;

另外一个问题是,添加这个触发器之后,可以使用简单的insert into来添加数据吗?

更新: 这是视图定义:

    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 (SELECT Company, EmployeeID, Emp_Status, Emp_LastName1, Emp_LastName2, Emp_FirstNames, dbo.InitCap(Emp_FullName) AS 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, 
                                                        
CASE WHEN SANMINA_EMAIL = 'xxxxxx.xxxx@sanmina.com' THEN 'xxxxxx.xxxx@sanmina.com' WHEN SANMINA_EMAIL IS NOT NULL AND SANMINA_EMAIL != '' AND SANMINA_EMAIL LIKE '%@sanmina.com%' THEN SANMINA_EMAIL WHEN Emp_Email IS NOT NULL AND Emp_Email != '' AND Emp_Email LIKE '%@sanmina.com%' THEN Emp_Email WHEN PERSONAL_EMAIL IS NOT NULL AND PERSONAL_EMAIL != '' AND PERSONAL_EMAIL LIKE '%@sanmina.com%' THEN PERSONAL_EMAIL ELSE NULL END AS SANMINA_EMAIL
                              
FROM XXX1AMTRESSXX.TRESS_SANM.dbo.Rex_Employees AS Rex_Employees_1
     WHERE        (Emp_Status = 'S')
     UNION ALL
     SELECT Company, EmployeeID, Emp_Status, Emp_LastName1, Emp_LastName2, Emp_FirstNames, dbo.InitCap(Emp_FullName) AS 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  SolutionsWebApp.dbo.Tbl_Non_TRESS_EMPLOYEES) AS derivedtbl_1
    WHERE (EmployeeID <> 005000170)

【问题讨论】:

将视图定义添加到您的问题中。如果视图从单个表中选择并且您从列列表中省略了问题常量,这应该可以工作(尽管我建议将SET NOCOUNT ON; 添加到触发器中)。 通常,当您在视图上使用而不是触发器时,触发器会处理插入以将数据放入相应的表中,而不仅仅是重复INSERT,老实说,这毫无意义。 @DanGuzman 我在帖子中添加了视图定义。 【参考方案1】:

我会说您视图中的一个字段与报告的一样,即常量或派生字段,因此您不能在此视图中插入行。它必须是一个基本的简单视图才能工作。毕竟,如果您考虑一下,如何将数据添加到派生字段中?我建议你插入到普通表中。

【讨论】:

我无权访问该表,因此我正在想办法通过该视图添加数据,但我想我会检查一下 我明白了。好吧,如果您无权访问该表,但您有权访问该视图,那么听起来您不应该插入数据,或者您没有权限。我建议正确地做事:不要破解。不要忘记 KISS 原则。 好的,在我访问该表并执行插入操作后,视图将要更新还是必须更新? 我猜你不太明白什么是视图。视图基本上是对表、其他视图等的查询。因此,如果视图是“创建视图 vw_rex_employees 作为从 rex_employees 中选择 companyid、employeeid、status、getdate() 作为 nowdate”,则执行“select * from vw_rex_employees”是实际上与“select * from (select companyid, employeeid ... etc) as f”相同。只需做一些关于理解观点的网络搜索。很抱歉,*** 并不是问这些非常基本的问题的地方。

以上是关于如何使用 INSTEAD OF 触发器在视图中插入数据?的主要内容,如果未能解决你的问题,请参考以下文章

sql - INSTEAD OF INSERT 触发器 - 插入前清除值

为啥 INSTEAD OF UPDATE 触发器的 INSERTED 表为空?

mssql instead of 触发器应用一-创建只读视图(view)的方法

INSTEAD OF与AFTER触发器

数据库触发器for,instead of和after的使用

MySQL 触发器中的“INSTEAD OF”,从 SQL Server 转换而来