我的触发器出现问题,它适用于单行更新,但对于多次更新,它会给出子查询返回多个值的错误。如何处理这个。
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
答案 0 :(得分: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
)
答案 1 :(得分:0)
我根本没有触发器。我重建你的表,然后创建一个模仿你当前表定义的视图。当然,我不知道你现在的桌子,所以我现在只能写出我最好的猜测。正如我所说的那样,我不明白你的状态逻辑在@month
显然同时是>=2
和<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
是否真的需要存在)