Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Однократное срабатывание триггера INSTEAD OF DELETE  [new]
londinium
Member

Откуда: Киев
Сообщений: 1199
Всем здравствуйте,
Есть
Microsoft SQL Server 2008 (SP2) - 10.0.4000.0 (Intel X86) 
	Sep 16 2010 20:09:22 
	Copyright (c) 1988-2008 Microsoft Corporation
	Enterprise Edition on Windows NT 5.2 <X86> (Build 3790: Service Pack 2)
и вот такая таблица
IF OBJECT_ID('Tmp_Payments',N'U') IS NOT NULL
  DROP TABLE Tmp_Payments
CREATE TABLE Tmp_Payments
(
  Tmp_ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
  Agree_ID INT NOT NULL,
  Pay MONEY NOT NULL,
  PayDate DATETIME NOT NULL DEFAULT GETDATE(),
  CurrencyCode_ID SMALLINT,
  IncomingDate DATETIME NOT NULL DEFAULT DATEADD(DD,1,GETDATE())
)  

INSERT Tmp_Payments(Agree_ID,Pay,CurrencyCode_ID)
 VALUES(127001,45.87,1),
       (128001,500.00,1)
На нее повешен триггер INSTEAD OF DELETE
IF OBJECT_ID(N'insofdelete_Payments',N'TR') IS NOT NULL
  DROP TRIGGER insofdelete_Payments
GO

CREATE TRIGGER insofdelete_Payments ON Tmp_Payments INSTEAD OF DELETE
AS
 BEGIN
  INSERT Tmp_Payments(Agree_ID,Pay,PayDate,CurrencyCode_ID,IncomingDate)
    SELECT Agree_ID,-Pay,PayDate,CurrencyCode_ID,IncomingDate
     FROM DELETED;
  IF(@@ERROR<>0)
    ROLLBACK TRAN;    
 END
GO     

Затык у меня в мозгах возник вот по какой причине- триггер должен срабатывать по такой логике: при первой попытке удаления записи из таблицы формировать отрицательный платеж и писать в таблицу Tmp_Payments, при второй и последующей попытках удаления
просто молча откатывать транзакцию без добавления отрицательного платежа, т.е.
--первый вызов
DELETE Tmp_Payments WHERE Tmp_ID=1
нужно вставить отрицательный платеж.

Второй вызов
--второй вызов. отрицательный платеж уже есть в таблице
DELETE Tmp_Payments WHERE Tmp_ID=1
откатить транзакцию без вставки платежа.

Как такое можно сделать и можно ли вообще?

С уважением, Londinium
3 авг 11, 23:39    [11068058]     Ответить | Цитировать Сообщить модератору
 Re: Однократное срабатывание триггера INSTEAD OF DELETE  [new]
invm
Member

Откуда: Москва
Сообщений: 9824
Как-то так:
use tempdb;
go
IF OBJECT_ID('Tmp_Payments',N'U') IS NOT NULL
  DROP TABLE Tmp_Payments
CREATE TABLE Tmp_Payments
(
  Tmp_ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
  Agree_ID INT NOT NULL,
  Pay MONEY NOT NULL,
  PayDate DATETIME NOT NULL DEFAULT GETDATE(),
  CurrencyCode_ID SMALLINT,
  IncomingDate DATETIME NOT NULL DEFAULT DATEADD(DD,1,GETDATE()),
  Referencing_Tmp_ID INT NULL REFERENCES Tmp_Payments (Tmp_ID)
)
go
IF OBJECT_ID(N'insofdelete_Payments',N'TR') IS NOT NULL
  DROP TRIGGER insofdelete_Payments
GO

CREATE TRIGGER insofdelete_Payments ON Tmp_Payments INSTEAD OF DELETE
AS
BEGIN
  declare @rc int = @@rowcount
  
  if @rc = 0
   return;
  
  select @rc;
   
  INSERT Tmp_Payments(Agree_ID,Pay,PayDate,CurrencyCode_ID,IncomingDate,Referencing_Tmp_ID)
    SELECT Agree_ID,-Pay,PayDate,CurrencyCode_ID,IncomingDate, Tmp_ID
    FROM DELETED d
    WHERE NOT EXISTS(SELECT * FROM Tmp_Payments WHERE Referencing_Tmp_ID = d.Tmp_ID);
 
  IF @@ERROR<>0 OR @@ROWCOUNT <> @rc
    IF @@TRANCOUNT > 0
      ROLLBACK TRAN;    
END
GO     
  
4 авг 11, 00:07    [11068133]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить