Instead of trigger in SQL Server loses SCOPE_IDENTITY?

后端 未结 6 2050
走了就别回头了
走了就别回头了 2020-12-01 10:30

I have a table where I created an INSTEAD OF trigger to enforce some business rules.

The issue is that when I insert data into this table, SCOPE_I

6条回答
  •  南方客
    南方客 (楼主)
    2020-12-01 11:20

    Like araqnid commented, the trigger seems to rollback the transaction when a condition is met. You can do that easier with an AFTER INSTERT trigger:

    CREATE TRIGGER [dbo].[TR_Payments_Insert]
       ON  [dbo].[Payment]
       AFTER INSERT
    AS 
    BEGIN
        SET NOCOUNT ON;
    
        IF 
        BEGIN
            ROLLBACK TRANSACTION
        END
    END
    

    Then you can use SCOPE_IDENTITY() again, because the INSERT is no longer done in the trigger.

    The condition itself seems to let two identical rows past, if they're in the same insert. With the AFTER INSERT trigger, you can rewrite the condition like:

    IF EXISTS(
        SELECT *
        FROM dbo.Payment a
        LEFT JOIN dbo.Payment b
            ON a.Id <> b.Id
            AND a.CustomerId = b.CustomerId
            AND (a.DateFrom BETWEEN b.DateFrom AND b.DateTo
            OR a.DateTo BETWEEN b.DateFrom AND b.DateTo)
        WHERE b.Id is NOT NULL)
    

    And it will catch duplicate rows, because now it can differentiate them based on Id. It also works if you delete a row and replace it with another row in the same statement.

    Anyway, if you want my advice, move away from triggers altogether. As you can see even for this example they are very complex. Do the insert through a stored procedure. They are simpler and faster than triggers:

    create procedure dbo.InsertPayment
        @DateFrom datetime, @DateTo datetime, @CustomerId int, @AdminId int
    as
    BEGIN TRANSACTION
    
    IF NOT EXISTS (
        SELECT *
        FROM dbo.Payment
        WHERE CustomerId = @CustomerId
        AND (@DateFrom BETWEEN DateFrom AND DateTo
        OR @DateTo BETWEEN DateFrom AND DateTo))
        BEGIN
    
        INSERT into dbo.Payment 
        (DateFrom, DateTo, CustomerId, AdminId)
        VALUES (@DateFrom, @DateTo, @CustomerId, @AdminId)
    
        END
    COMMIT TRANSACTION
    

提交回复
热议问题