SQL Server触发器以处理多个更新行。子查询返回多个值

时间:2013-05-01 13:55:21

标签: sql sql-server database triggers

我将此触发器用于单行插入或更新,但是当我尝试一次更新多行时,它会给出错误,即子查询返回的值超过一个值。

例如

update paymentdata
set stat=1 

触发器代码在这里

USE [AGP]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[OnpaymentUpdate]
   ON  [dbo].[paymentData]
 AFTER UPDATE --operations you want trigger to fire on
AS 

BEGIN   


    SET NOCOUNT ON;

    DECLARE @customerID NCHAR(50),  @lastpaymentDate DATETIME, @stat nchar(50), @month int;

    SET @customerID= (SELECT customerID FROM inserted)  --table inserted contains inserted rows (or new updated rows)

    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
            )

    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)
 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

1 个答案:

答案 0 :(得分:0)

如果我理解正确,那么以下内容应该有效...试一试并更正您发现的任何语法错误:
注意:就个人而言,我不会使用触发器。我会将此代码放在应用付款的商店程序中。

 ALTER TRIGGER [dbo].[OnpaymentUpdate]
   ON  [dbo].[paymentData]
 AFTER UPDATE --operations you want trigger to fire on
 As 

BEGIN   
    Declare @today datetime = dateAdd(dd, datediff(dd, 0, getDate()), 0)
    Declare @custInfo table 
        (custId integer Primary Key not null, 
         stat varChar(30) not null,
         balance bigint not null,
         lastPymnt datetime not null, 
         lastGap smallint not null)

    Insert @custInfo(custId, stat, balance, lastPymnt, lastGap)
    Select i.customerId, i.stat, 
        totalprice-(paidAmount+concession), 
        MAX(paymentDate),
        Min(datediff(month, paymentDate, @today))
    From inserted i 
       join paymentReceipt r On r.customerId = i.customerId
       join PaymentData d On d.CustomerId = i.customerId
    Group By i.customerId, i.stat, 
        d.totalprice-(d.paidAmount + d.concession)


    Update pd Set
       balanceAmount = i.balance,
       lastpaymentDate = i.lastPymnt,
       stat = case When lastGap >=2  and i.stat!='Cancel' 
                and i.stat!='Refund' And i.stat!='Refunded' 
                and i.stat!='Transfered' and i.stat!='Transfer') Then Case
                   When @month >= 2 And i.stat='Defaulter' Then 'Regular'
                   When @balance<=0 Then 'Payment Completed'
                   Else 'Defaulter' End
                Else Case @stat 
                   When 'Refund' Then 'Refunded'
                   When 'Cancled' Then 'Cancel'
                   When 'Transfer' Then 'Transfered' End
                End
    From PaymentData pd Join @custInfo i 
       On i.custId = pd.customerID
END