在更新语句中引发错误

时间:2014-03-04 07:50:36

标签: sql-server tsql stored-procedures sql-server-2012 common-table-expression

我正在运行SP以更新帐户中的余额。这是SP代码:

CREATE procedure UpdateBalance(@LedgerID as int,@TransDate as DateTime,@Neg as smallint) as
Begin
Declare @OpenBal as decimal(12,2)
Select Top 1 @OpenBal=Balance From Trans Inner Join TransGroup On Trans.TGID=TransGroup.TGID And TransDate<@TransDate Where LedgerID=@LedgerID Order By TransDate,TransGroup.TGID;
With CTE as
(Select TransGroup.TGID,LedgerID,Amount,Balance,Sum(Amount) Over(Order By TransDate,TransGroup.TGID) as 'Total' From Trans Inner Join TransGroup On Trans.TGID=TransGroup.TGID And TransDate>=@TransDate Where LedgerID=@LedgerID)
Update CTE Set Balance=Total+@OpenBal
End

SP运行正常并从@TransDate开始更新帐户余额。

@Neg参数当前未使用,其值为0,-1或1。

如果@Neg参数不为零,我希望如果更新Total+@OpenBal值的符号与@Neg参数的符号不匹配,则SP会失败。

例如,如果@Neg为1,则Balance应始终为正数,如果SP在任何行变为负数,则SP应失败。

当然,一个简单的解决方案是将Update语句放在事务中,运行Select语句来检查负余额,然后相应地提交或回滚事务。但是我想知道是否有办法在Update CTE Set Balance=Total+@OpenBal语句中引发错误,以便它自动回滚所有内容。

我尝试过这样的事情 - 但是我知道Throw语句中不能调用Case

Update CTE Set Balance=Case @Neg When 0 Then Total+@OpenBal When 1 Then Case When Total+@OpenBal<0 Then Throw Else Total+@OpenBal End When -1 Then Case When Total+@OpenBal<0 Then Throw Else Total+@OpenBal End End

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您不能在UPDATE语句中抛出自定义异常。

您有几个选择:

  1. 更新时使用INSTEAD OF触发器。如果需要,可以阻止更新发生,抛出自定义错误等。
  2. 在该过程中,执行Total + @OpenBal计算并将它们插入表变量中。 SELECT为无效值,如果找到一些可以抛出自定义错误;否则,将您的表变量与您需要的任何其他内容联系起来并进行更新
  3. 通过插入错误值进行投掷是一种破解,并且错误将使使用存储过程的任何人感到困惑。看起来你的代码有错误。

    我有点好奇 - 你为什么要单独存储标志,然后验证另一个值是否有相同的标志?你的设计听起来是非规范化的。