Sql server 在INSERT上验证表记录的总和
我有一个记录各种账户交易的表格: 账户交易Sql server 在INSERT上验证表记录的总和,sql-server,database,sql-server-2008,tsql,Sql Server,Database,Sql Server 2008,Tsql,我有一个记录各种账户交易的表格: 账户交易 AccountTransactionID int NOT NULL (PK) AccountID int NOT NULL (FK) Amount decimal NOT NULL 在将金额为负数的记录插入此表时,我需要验证指定帐户的金额列之和是否大于零。如果新记录将导致该总和降至零以下,则不应插入该记录 例如,如果我有以下记录,则不允许为AccountID5插入-8.00的金额: AccountTransactionID Account
AccountTransactionID int NOT NULL (PK)
AccountID int NOT NULL (FK)
Amount decimal NOT NULL
在将金额为负数的记录插入此表时,我需要验证指定帐户的金额列之和是否大于零。如果新记录将导致该总和降至零以下,则不应插入该记录
例如,如果我有以下记录,则不允许为AccountID
5插入-8.00的金额:
AccountTransactionID AccountID Amount
---------------------------------------------
1 5 10.00
2 6 15.00
3 5 -3.00
实现这一目标的最佳方法是什么?检查存储过程中的约束、触发器或仅检查此条件?您可以在insert中添加
where
子句:
insert YourTable
(AccountID, Amount)
select @AccountID, @Amount
where 0 <=
(
select @Amount + sum(Amount)
from YourTable
where AccountID = @AccountID
)
插入表格
(帐户ID,金额)
选择@AccountID、@Amount
其中0可以进行简单检查:
DECLARE @TheSum decimal(18,2)
SET @TheSum = (SELECT SUM(MyCol) FROM MyTable WHERE AccountID = @SomeParameter)
If @TheSum > 0
BEGIN
--do your insert
END
...
当金额不允许时,您希望发生什么行为?它可能会引发错误。我的应用程序中有逻辑,这样这个条件甚至不应该到达数据库,但是我也希望在数据层有一个级别的保护。如果accountID是您的过程的参数之一,我只需要使用一个子查询,它将当前值(插入前)相加,然后作为where子句的条件进行比较。如果受影响的记录小于1,则可以引发适当的异常。不过,我相信还有其他方法可以做到这一点。请检查您的Where
子句。这看起来不正确,为什么要将AccountID分配给@Amount?这会引入竞争条件。另一个过程可能会减少set
语句和insert
语句之间的总和。使用事务是否可以缓解竞争条件?具有适当隔离级别的事务将有助于减少并发事务的问题:是的,“可重复读取”或“可序列化”的事务将解决这一问题。此外,此答案在加法之前检查总和,它可能应该在事务之后检查总和。目标是防止出现负和,而不是防止负和的增加。