0

我的触发器有问题,它适用于单行更新,但对于多次更新,它会给出错误,即子查询返回一个以上的值。如何处理。

    GO

    ALTER TRIGGER [dbo].[OnpaymentUpdate]
       ON  [dbo].[paymentData]
     AFTER UPDATE 
    AS 
    BEGIN  
        SET NOCOUNT ON;  
        DECLARE @customerID NCHAR(50),  @lastpaymentDate DATETIME, @stat nchar(50), @month int;
        SET @customerID= (SELECT customerID FROM inserted)  
SET @stat= (SELECT stat FROM inserted) --table inserted contains inserted rows (or new updated rows)
        set @lastpaymentDate =  (SELECT MAX(paymentDate) FROM paymentReceipt where customerID=@customerID)  
    SET @month= (SELECT DATEDIFF(MONTH,  @lastpaymentDate,GETDATE()))
     DECLARE @balance BIGINT
        SET @balance = 
                (
                    SELECT (totalprice-(paidAmount+concession)) 
                    FROM paymentData
                    WHERE customerID = @customerID
                )
                 Declare @paid int
                 SET @paid = 
                (
                    SELECT paidAmount 
                    FROM paymentData
                    WHERE customerID = @customerID
                )


        UPDATE PaymentData
            SET balanceAmount = @balance ,
              lastpaymentDate=@lastpaymentDate
        WHERE customerID = @customerID


    if (@month >=2  and @stat!='Cancel' and @stat!='Refund' And @stat!='Refunded' and @stat!='Transfered' and @stat!='Transfer')
    Begin

    IF  (@month <2 and @stat='Defaulter')
     SET @stat='Regular'
     IF (@balance<=0 and @paid >0)
     SET @stat='Payment Completed'
     else
     SET @stat='Defaulter'
     End
    else
    Begin

    if @stat='Refund'
     Set @stat='Refunded'
     if @stat='Cancled'
     Set @stat='Cancel'
     if @stat='Transfer'
     Set @stat='Transfered'
    End

     UPDATE PaymentData
            SET stat =@stat

        WHERE customerID = @customerID

    END
4

2 回答 2

0

我根本不会有触发器。我会重建你的表,然后创建一个模仿你当前表定义的视图。当然,我不知道你目前的表,所以我现在只能写我最好的猜测。正如我所说,我不明白你在底部的状态逻辑@month显然可以同时同时是>=2and <2,所以我让那部分不完整:

create table dbo._PaymentData (
    CustomerID nchar(50) not null,
    _Status nchar(50) not null,
    TotalPrice bigint not null,
    PaidAmount bigint not null,
    Concession bigint not null,
    Balance as TotalPrice - (PaidAmount + Concession)
)
go
create view dbo.PaymentData
with schemabinding
as
    with RecentReceipts as (
        select CustomerID,MAX(PaymentDate) as LastPayment from dbo.PaymentReceipt group by CustomerID
    ), MonthsDelinquent as (
        select CustomerID,LastPayment,DATEDIFF(month,LastPayment,CURRENT_TIMESTAMP) as Months from RecentReceipts
    )
    select
        pd.CustomerID,
        TotalPrice,
        PaidAmount,
        Concession,
        Balance,
        LastPayment,
        CASE
            WHEN _Status in ('Cancel','Refund','Refunded','Transfered','Transfer')
            THEN _Status
            WHEN md.Months > 2 and Balance<= 0 and PaidAmount > 0
            THEN 'Payment Complete'
            --More conditions here to work out the actual status
        END as Status
    from
        dbo._PaymentData pd
            left join
        MonthsDelinquent md
            on
                pd.CustomerID = md.CustomerID
go

现在,我们不需要触发器——表和/或视图总是正确的(尽管视图上可能需要触发器来允许Status/_Status被更新——目前尚不清楚这是否有必要或是否_Status实际需要完全存在)

于 2013-06-04T13:09:17.590 回答
0

在此过程中是否可以添加多个 CustomerID?这条线很麻烦:

   SET @customerID= (SELECT customerID FROM inserted)  
   SET @stat= (SELECT stat FROM inserted) --table inserted contains inserted 

如果保证 customerID 和 stat 对于所有行都是一致的,您可以使用 MAX 修复它,例如:

   SET @customerID= (SELECT MAX(customerID) FROM inserted)  
   SET @stat= (SELECT MAX(stat) FROM inserted) --table inserted contains inserted 

但是,如果不能保证这些项目对于插入的所有行都是一致的,那么您将遇到麻烦。如果是这种情况,您将需要一个光标来浏览这些值。

也改成这个:

    SET @balance = 
            (
                SELECT SUM( (totalprice-(paidAmount+concession)) ) 
                FROM paymentData
                WHERE customerID = @customerID

            )
             Declare @paid int
             SET @paid = 
            (
                SELECT SUM(paidAmount) 
                FROM paymentData
                WHERE customerID = @customerID
            )
于 2013-06-04T12:19:38.483 回答