触发允许删除视图

时间:2018-03-25 12:16:52

标签: sql sql-server triggers

我想创建一个允许在视图中进行删除的触发器。修改涉及多个表,当我尝试删除一行视图时出错。

以下是我的表格:

create table Etudiant 
(
    mat int,
    nom char(25),
    prenom char(25),
    datenais datetime
)

create table Cours 
(
    ccode int, 
    nomcours char(25),
    enseignant char(25),
    credits char(255)
)

create table Examen 
(
    mat int,
    ccode int,
    dateExa datetime, 
    note char(25)
)

我的观点:

create view SYNT_EXAMEN (mat, nom, prenom, ccode, dateExa, note)
as 
      select etudiant.mat, nom, prenom, cours.ccode, dateExa, note 
      from etudiant 
      join examen on etudiant.mat = examen.mat
      join cours on cours.ccode = examen.ccode

我的触发器:

CREATE TRIGGER declencheur_suppression
ON synt_examen
INSTEAD OF DELETE
AS 
BEGIN
    DELETE FROM synt_examen 
        SELECT nom FROM inserted i
END

当我执行我的触发器时,我想删除我的视图中的一行(例如从synt_examen中删除nom =' dupont')而没有错误:

"视图或功能' synt_examen'无法更新,因为更改会影响多个基表。"

2 个答案:

答案 0 :(得分:1)

视图上的而不是删除触发器的目的是从视图所依赖的表中删除数据。您无法直接从视图中删除,这就是您必须使用instead of delete触发器的原因。

但这并不意味着在触发器本身你可以从视图中删除 - 这是没有意义的。相反,在触发器中,您需要指示SQL Server从哪里删除 - 您可以通过为要从中删除的每个表构造一个delete语句来实现。如果要从多个表中删除,可以在触发器中指定多个删除语句。

根据您发布的代码,我认为您正在寻找类似的内容:

CREATE TRIGGER declencheur_suppression
ON synt_examen
INSTEAD OF DELETE
AS 
BEGIN
    DELETE t
    FROM Etudiant t
    JOIN deleted d ON t.nom = d.nom
END

如果您根据Etudiant列从视图中删除记录,则此触发器会删除nom中的记录。

答案 1 :(得分:0)

Zohar答案的替代方法是,不删除记录(出于审计目的),而是标记记录已删除,并更改视图以反映这一点。

按照上述步骤创建触发器,但将其更改为UPDATE语句...

USE [yourdatabase];
GO
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
CREATE TRIGGER declencheur_suppression
ON synt_examen
INSTEAD OF DELETE
AS 
   UPDATE t
   SET t.Status = 0
   FROM Etudiant AS t
      INNER JOIN deleted d ON t.ID = d.ID
GO

当然,您将需要添加另一个名为“ Status”的列,并将其默认设置为1以表示“活动”(或未删除)。如果为0,则表示已被删除。

要反映这一点,请更改视图以包含WHERE之类的WHERE Etudiant = 1子句。

我更喜欢这种方法,因为出于良好的DBA惯例,应尽可能避免物理删除记录