2016-06-29 5 views
1

Ich habe zwei Tabellen; der erste heißt PAYMENT und der zweite ist eine historische Tabelle mit dem Namen RecordPay.Historische Tabelle in SQL Server

Ich habe zwei Trigger, der erste ist für einfügen, um in die historischen Tabellen Datensätze aus Payment Tabelle einfügen. Hier

ist der Code:

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) 

Das funktioniert gut, mein Problem, wenn ich eine Reihe von PAYMENT löschen, in RecordPay der Datensatz vorhanden ist, und dann, wenn ich eine andere Zeile in PAYMENT Einsatz hatte ich zwei RG_NO whith die gleiche Nummer.

Zum Beispiel füge ich eine Zeile in PAYMENT mit RG_NO = 1 dann löschte ich, und ich erstelle eine andere Zeile mit RG_NO = 2, in der recordPay (historische Tabelle) bekomme ich zwei Zeilen mit RG_NO = 1. Hier

ist der Auslöser für löschen, aber es nicht

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 den klassischen Fehler von Triggern gemacht; Angenommen, es gibt nur eine Zeile in 'INSERTED'. Ein weiterer Punkt - in Zahlungsverarbeitungszeilen werden * nie * gelöscht, eine Zahlungsumkehr erfolgt in der Regel durch eine andere Zahlung, um die erste zu stornieren. – Jamiec

+0

Vielen Dank für Ihre Antwort, aber können Sie ein Beispiel geben. Ich verstehe es nicht sehr gut – hollyx

+1

Wenn Sie eine Zahlung von '5' löschen wollten, würden Sie diese Reihe von Zahlungen nicht löschen, Sie würden eine neue Zahlung von' -5' eingeben, um es auszubalancieren – Jamiec

Antwort

1

Ihre Trigger wird BREAK so schnell funktioniert wie eine INSERT Anweisung fügt mehr als 1 Zeile zu einer Zeit - weil in diesem Fall Ihre Trigger ruft einmal für die INSERT-Anweisung und Inserted wird mehrere Zeilen enthalten.

Welche von diesen 10 Reihen wählen Sie von hier ??

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 

Es ist willkürlich und nicht-deterministisch - und Sie werden einfach ignorieren alle anderen Zeilen in Inserted.

Sie benötigen Trigger neu zu schreiben, dies zu berücksichtigen:

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

Vielen Dank – hollyx