2016-06-29 3 views
1

두 테이블이 있습니다. 첫 번째 이름은 PAYMENT이고 두 번째 테이블은 RecordPay이라는 역사적인 테이블입니다.SQL Server의 내역 표

나는 두 개의 트리거를 가지고 있는데, 첫 번째는 삽입하기 위해 Payment 테이블의 기록 테이블 레코드에 삽입하기위한 것입니다. 내가 RecordPay 레코드가 존재하며, 내가 PAYMENT에서 다른 행을 삽입 할 때 나는 두 RG_NO 파크 있었다에서, PAYMENT에서 행을 삭제할 때, 내 문제

ALTER TRIGGER [dbo].[INSERT_HIST] 
ON [dbo].[PAYMENT] 
FOR INSERT 
AS 
BEGIN 
    DECLARE @User_op varchar(50) 
    DECLARE @RGNO varchar(50) 

    DECLARE @PAYEUR varchar(50) 
    DECLARE @DATESYS SMALLDATETIME 
    DECLARE @RG_DATE SMALLDATETIME 
    DECLARE @RG_Montant varchar(50) 

    SELECT @User_op = cbUserName 
    FROM cbUserSession 
    WHERE cbSession = @@SPID 

    SELECT @PAYEUR = CT_NumPayeur FROM INSERTED 

    SELECT @DATESYS = GETDATE() 
    SELECT @RG_Montant = RG_Montant FROM INSERTED 
    SELECT @RG_DATE = RG_DATE FROM INSERTED 
    SELECT @RGNO = RG_No FROM INSERTED 

    INSERT INTO RecordPay (RG_NO, PAYEUR, CAISSIER, Montant, DATESYS, DATECAI) 
    VALUES (@RGNO, @PAYEUR, @user_op, @RG_Montant, @DATESYS, @RG_DATE) 

이 잘 작동 : 여기

코드입니다 같은 번호.

예를 들어, PAYMENT에 RG_NO = 1로 행을 삽입 한 다음 삭제하고 RG_NO = 2 인 다른 행을 recordPay (기록 테이블)에 작성합니다. RG_NO = 1로 두 행을 얻습니다. 여기

은 삭제에 대한 트리거이지만 한 번에하는 즉시 INSERT 문이 1 개 이상의 행을 삽입으로

ALTER TRIGGER [dbo].[DEL_HIST] 
ON [dbo].[PAYMENT] 
AFTER DELETE 
AS 
BEGIN 


DECLARE @User_op varchar(50) 
DECLARE @RGNO varchar(50) 

DECLARE @PAYEUR varchar(50) 
DECLARE @DATESYS SMALLDATETIME 
DECLARE @RG_DATE SMALLDATETIME 
DECLARE @RG_Montant varchar(50) 


SELECT @PAYEUR = CT_NumPayeur FROM DELETED 

SELECT @RG_Montant = RG_Montant FROM DELETED 
SELECT @RG_DATE = RG_DATE FROM DELETED 
SELECT @RGNO = RG_No FROM DELETED 

DELETE FROM RECORDPAY WHERE 
[email protected] and PAYEUR= @PAYEUR and [email protected]_op and [email protected]_Montant 
END 
+5

의 youve 트리거의 고전적인 실수를; 'INSERTED'에 단지 1 행만 있다고 가정합니다. 지불 처리 행의 또 다른 포인트는 * 절대 * 삭제되지 않으며, 지불 반전은 일반적으로 첫 번째를 무효화하기 위해 다른 지불을 통해 수행됩니다. – Jamiec

+0

답장을 보내 주셔서 감사하지만 예제를 드릴 수 있습니까? 나는 그것을 잘 얻지 못한다. – hollyx

+1

만약 '5'의 지불을 지우고 싶다면, 그 지불 행을 지우지 않을 것이고, 새로운 지불을'-5'로 입력하면 균형을 이룰 것이다. – Jamiec

답변

1

귀하의 트리거 BREAK 작동하지 않습니다 -이 경우, 트리거 때문에 INSERT 문에는 번이 번이고, Inserted 번에는 여러 행이 포함됩니다.

여기서 10 개의 행 중 어느 것을 선택 하시겠습니까 ??

SELECT @PAYEUR = CT_NumPayeur FROM INSERTED 
SELECT @RG_Montant = RG_Montant FROM INSERTED 
SELECT @RG_DATE = RG_DATE FROM INSERTED 
SELECT @RGNO = RG_No FROM INSERTED 

은 임의적이고 비 결정적이다 - 당신은 단순히 Inserted에서 다른 모든 행을 무시합니다.

당신은이 점을 고려하기 위해 트리거를 재 작성해야합니다

ALTER TRIGGER [dbo].[INSERT_HIST] 
ON [dbo].[PAYMENT] 
FOR INSERT 
AS 
BEGIN 
    DECLARE @User_op varchar(50) 

    SELECT @User_op = cbUserName 
    FROM cbUserSession 
    WHERE cbSession = @@SPID 

    -- insert a record for ALL the rows that were inserted into 
    -- your history table in a single, elegant, set-based statement 
    INSERT INTO RecordPay (RG_NO, PAYEUR, CAISSIER, Montant, DATESYS, DATECAI) 
     SELECT 
      RG_No, CT_NumPayeur, @User_op, RG_Montant, SYSDATETIME(), RG_Date 
     FROM 
      Inserted 
+1

정말 고마워요. – hollyx