Sql server SQL触发器,返回多个值的子查询。

Sql server SQL触发器,返回多个值的子查询。,sql-server,triggers,Sql Server,Triggers,我的触发器有问题,它适用于单行更新,但对于多个更新,它会给出一个错误,即子查询返回的值不止一个。如何处理这个问题 GO ALTER TRIGGER [dbo].[OnpaymentUpdate] ON [dbo].[paymentData] AFTER UPDATE AS BEGIN SET NOCOUNT ON; DECLARE @customerID NCHAR(50), @lastpa

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

    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

是否可以在流程中添加多个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
            )

我根本就没有扳机。我将重建您的表,然后创建一个模仿当前表定义的视图。当然,我不知道你们当前的表格,所以我现在只能写我最好的猜测。正如我所说,我不理解你在底部的状态逻辑,@month显然可以同时是>=2,你甚至在你的问题中包含了线索,作为注释:插入的表包含插入的行或新更新的行-注意,表中显示的是行-但您试图从中选择一个值并将其分配给标量变量。这可能会作为基于集合的操作重新写入,或者甚至可能被计算列和/或索引视图取代-但我们需要先了解表结构-例如,特定customerID的PaymentData中是否只有一行?最后,我需要了解IF@month>=2和。。。开始如果@month<2且…-第二个if语句何时才能满足?是的,特定customerID的paymentData中只有一行。customerID不是常量。例如,对于每个客户,paymentdata表中只有一条记录,但paymentreceipt表中有许多记录。好的,那么问题不在于paymentdata,所以不需要在那里求和。那你的房间呢?SQL server当然会允许您为不同的客户插入多个记录,但您是否有其他业务逻辑可以防止这种情况发生?如果是这样,那么您可以安全地使用MAX,但为了真正安全,您可能更喜欢光标。脱离主题,这种逻辑最好在触发器之外完成,因为触发器更不透明,这实际上是您的域逻辑。JMO
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