2010-11-23 3 views
8

Je suis en train d'exécuter le déclencheur suivant:Créer déclencheur éviter d'insérer

create trigger t23 
on studies 
after insert, update, delete 
as 
begin 
REFERENCING NEW ROW NewStudent 
FOR EACH ROW 
WHEN (30 <= (SELECT SUM(credits) FROM Studies) 
DELETE FROM NewStudent N 
WHERE N.spnr = NewStudent.spnr 
end 

Je suis en train de créer un déclencheur qui insère seulement un étudiant si les crédits est < ou == pour « 30 ». Le "Crédits" est un type int.

Je reçois beaucoup d'erreurs en essayant d'implémenter ce déclencheur. J'ai vraiment tout essayé et je suis à court d'options. Est-ce que quelqu'un qui est expert dans le domaine pourrait me pointer dans la bonne direction?

+1

Quel SGBD utilisez-vous? –

Répondre

12

L'exemple « L'utilisation d'un DML déclencheur AFTER appliquer une règle d'affaires entre les tables PurchaseOrderHeader et fournisseurs » dans la documentation CREATE TRIGGER MSDN ne exaclty ce que vous cherchez:

USE AdventureWorks2008R2; 
GO 
IF OBJECT_ID ('Purchasing.LowCredit','TR') IS NOT NULL 
    DROP TRIGGER Purchasing.LowCredit; 
GO 
-- This trigger prevents a row from being inserted in the Purchasing.PurchaseOrderHeader table 
-- when the credit rating of the specified vendor is set to 5 (below average). 

CREATE TRIGGER Purchasing.LowCredit ON Purchasing.PurchaseOrderHeader 
AFTER INSERT 
AS 
DECLARE @creditrating tinyint, @vendorid int; 
IF EXISTS (SELECT * 
      FROM Purchasing.PurchaseOrderHeader p 
      JOIN inserted AS i 
      ON p.PurchaseOrderID = i.PurchaseOrderID 
      JOIN Purchasing.Vendor AS v 
      ON v.BusinessEntityID = p.VendorID 
      WHERE v.CreditRating = 5 
     ) 
BEGIN 
RAISERROR ('This vendor''s credit rating is too low to accept new purchase orders.', 16, 1); 
ROLLBACK TRANSACTION; 
RETURN 
END; 

La clé est ici ROLLBACK TRANSACTION , adaptez simplement l'exemple en fonction de vos besoins et vous avez terminé. Editer: Cela devrait accomplir ce que vous cherchez, mais je ne l'ai pas testé, donc votre kilométrage peut varier.

create trigger dbo.something after insert as 
begin 
    if exists (select * from inserted where sum(credits) > 30) 
    begin 
     rollback transaction 
     raiserror ('some message', 16, 1) 
    end 
end 

Une autre modification, basée sur certaines hypothèses (s'il vous plaît noter que j'écrit ce script à la volée puisque je ne peux pas tester en ce moment):

create table dbo.students 
(
    student_id int not null, 
    name varchar (50) not null 
) 

create table dbo.courses 
(
    course_id int not null, 
    name varchar (50) not null, 
    required_credits int not null 
) 

create table dbo.results 
(
    student_id int not null, 
    course_id int not null, 
    course_result int not null 
) 

create trigger dbo.check_student_results on dbo.results after insert as 
(
    declare @check int 

    select @check = count(*) 
    from inserted as a 
    join dbo.courses as b on b.course_id = a.course_id 
    where b.required_credits > a.course.result 

    if @check <> 0 
    begin 

     rollback transaction 

     raiserror('The student did not pass the course.', 16, 1) 

    end 
) 

De cette façon, lorsque vous insérez des enregistrements dans la dbo.results la contrainte vérifie si l'étudiant a réussi le cours et annule l'insertion si nécessaire. Cependant, il est préférable de vérifier cela dans la couche application.

+1

+1 pour mentionner "... il est préférable de vérifier cela dans la couche d'application." – BigM

Questions connexes