2016-10-15 4 views
1

Триггер должен реагировать на удаление строки из таблицы. Поставщики, если в таблице есть материалы. Поставки от этого поставщика, триггер должен отменить удаление. Этот код позволяет удалить оба поставщиков с поставками и поставщиками без питания:Не понимайте, как срабатывают триггеры

CREATE TRIGGER SuppliersDeleteCondition 
ON Suppliers 
FOR DELETE 
AS 
IF EXISTS (
      SELECT 1 
      FROM Supplies Ses 
      JOIN DELETED D 
       ON D.SupplierID=Ses.SupplierID 
     ) 
BEGIN 
    RAISERROR ('This supplier has some supplies', 16, 1) 
    ROLLBACK TRANSACTION 
END; 

таблицы Прибл посмотреть являются:

Поставщики (SupplierID, имя, адрес, BankDetails), товары (SupplyID, SupplierID, ProductID , ImplementationPeriod, вес, цена)

Вот CREATE TABLE:

CREATE TABLE Suppliers 
     (
     SupplierID INT IDENTITY, 
     Name VARCHAR(150) NOT NULL UNIQUE, 
     Address VARCHAR(900) NOT NULL, 
     BankDetails VARCHAR(9) NOT NULL UNIQUE, 

     CONSTRAINT pk_SupplierID PRIMARY KEY (SupplierID), 
     CONSTRAINT chk_Name_Suppliers CHECK (NOT Name LIKE '%[^a-z ]%' AND NOT Name LIKE '[ ]%' AND NOT Name LIKE '%[ ]' AND NOT Name LIKE '%[ ][ ]%'), 
     CONSTRAINT chk_Address_Suppliers CHECK (NOT Address LIKE '%[^a-zA-z0-9,./ ]%' AND NOT Address LIKE '[ ]%'), 
     CONSTRAINT chk_BankDetails_Suppliers CHECK (BankDetails LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]') 
     ); 
CREATE TABLE Supplies 
     (
     SupplyID INT IDENTITY, 
     SupplierID INT, 
     ProductID INT, 
     ImplementationPeriod DATE NOT NULL, 
     Weight REAL NOT NULL, 
     Price MONEY NOT NULL, 

     CONSTRAINT pk_SupplyID PRIMARY KEY (SupplyID), 
     CONSTRAINT fk_SupplierID FOREIGN KEY (SupplierID) REFERENCES Suppliers(SupplierID) ON DELETE CASCADE, 
     CONSTRAINT fk_ProductID FOREIGN KEY (ProductID) REFERENCES Products(ProductID) ON DELETE CASCADE, 
     CONSTRAINT chk_Weight_Supplies CHECK (Weight > 0) 
     ); 

Когда я удалить строку, как это:

DELETE FROM Suppliers WHERE SupplierID=18 

эта строка удалена, и я не получил ошибку

+1

Чтобы предотвратить удаление, вы должны использовать ограничение внешнего ключа, а не триггер. –

+0

Я знаю, что лучше использовать FK, но можно ли использовать триггер? – salkcid

+0

@salkcid, да, можно использовать триггеры для обеспечения ссылочной целостности, поскольку это был единственный способ сделать это до того, как ограничения RI были введены в SQL Server 20 лет назад. Поместите 'CREATE TABLE' и полный скрипт, который воспроизводит проблему. –

ответ

3

У вас есть внешний ключ с опцией DELETE CASCADE поэтому удаление триггера является излишним. Триггер AFTER DELETE будет запускаться после строк из поставщиков, и материалы были удалены, поэтому никакие строки никогда не будут соответствовать предикату EXISTS. Здесь нет необходимости в триггере, если вы не удалите внешний ключ, который я бы не рекомендовал. Пусть SQL Server сделает для вас работу.

+0

Большое спасибо, проблема решена. – salkcid

Смежные вопросы