2016-06-29 20 views
1

私は2つのテーブルを持っています。最初の名前はPAYMENTで、2番目のテーブルはRecordPayという履歴テーブルです。SQL Serverの履歴テーブル

私は2つのトリガーを持っていますが、最初のテーブルは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) 

これは私がRecordPayで、PAYMENTから行を削除すると、レコードが存在し、よく私の問題を動作し、私はPAYMENTで別の行を挿入したとき、私は2 RG_NO whithを持っていました同じ番号。

たとえば、PAYMENTにRG_NO = 1の行を挿入して削除した後、RG_NO = 2の別の行を作成すると、recordPay(履歴表)にRG_NO = 1の2行が表示されます。ここで

は、削除のためのトリガーですが、それは

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

ホードは、トリガーの古典誤りを作りました。 'INSERTED'には1行しかないと仮定します。別の支払い処理の行は決して削除されません。支払いの取り消しは通常、最初の支払いを無効にするために別の支払いを行うことによって行われます。 – Jamiec

+0

あなたの応答に感謝しますが、例を挙げることができます。私はそれを非常にうまく受け取りません。 – hollyx

+1

あなたが '5'の支払いを削除したいなら、あなたは支払いの行を削除しません、それを平衡させるために' -5'の新しい支払いを入力します – Jamiec

答えて

1

あなたのトリガは、すぐINSERT文は一度に複数の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

関連する問題