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