Reputation: 13
I want to create a trigger which allows to make deletions in a view. The modification relates multiples tables and I have an error when I try to delete a line of my view.
Here are my tables :
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)
)
My view :
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
My trigger :
CREATE TRIGGER declencheur_suppression
ON synt_examen
INSTEAD OF DELETE
AS
BEGIN
DELETE FROM synt_examen
SELECT nom FROM inserted i
END
When I execute my trigger I want to delete a line (for example delete from synt_examen where nom = 'dupont') of my view without error :
"The view or function 'synt_examen' can not be updated because the change affects more than one base table."
Upvotes: 1
Views: 2203
Reputation: 4888
An alternative to Zohar's answer, is to not delete records (for auditing purposes), but to flag the record deleted, and change your view to reflect this.
i.e.
Create the trigger as per the above, but alter it into an UPDATE statement...
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
Of course you will need to add another column called 'Status
' and default it to 1 for ACTIVE (or non deleted). When it's 0, it implies it's been deleted.
To reflect that, change your view to have a WHERE
clause such as WHERE Etudiant = 1
.
I prefer this method because physically deleting records should be avoided as much as possible, for good DBA practice.
Upvotes: 1
Reputation: 82504
The point of an instead of delete trigger on the view is to delete the data from the tables on which the view relies on. You can't delete directly from the view which is why you must use an instead of delete
trigger.
But this doesn't mean that in the trigger itself you can delete from the view - that wouldn't make sense. Instead, in the trigger you need to instruct SQL Server what do you want to delete from where - you do that by constructing a delete statement for each table involved you want to delete from. You can specify multiple delete statements in your trigger if you want to delete from multiple tables.
Based on the code you posted, I think you are looking for something like this:
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
This trigger will delete records from the Etudiant
if you deleted them from the view, based on the nom
column.
Upvotes: 1