我想创建一个允许在视图中进行删除的触发器。修改涉及多个表,当我尝试删除一行视图时出错。
以下是我的表格:
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'无法更新,因为更改会影响多个基表。"
答案 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惯例,应尽可能避免物理删除记录。