我有一个带有检查约束的待处理订单表,以防止人们订购我们没有库存的商品。这需要我创建一个计数器函数来决定插入是否可以发生。它一直工作,直到库存中剩下1个项目,然后我收到一条消息,说明我们缺少该项目的库存。我认为这是一个脏的读取问题,但即使在引入ReadPast提示之后我仍然会看到这种行为。还有其他因素导致这个问题吗?或者我需要以不同方式设置隔离级别吗?
我尝试使用sprokID调用此函数并返回true,这就是为什么我在插入过程中会发生脏读的原因。
ALTER TABLE [dbo].[PendingSprokOrders] WITH CHECK ADD CONSTRAINT [CK_SprokInStock] CHECK (([dbo].[SprokInStockCount]([SprokID])=(1)))
FUNCTION [dbo].[SprokInStockCount] ( @SprokId INT )
RETURNS INT
AS
BEGIN
DECLARE @Active INT
SET @Active = ( SELECT COUNT(*)
FROM [PendingSprokOrders] AS uac WITH(READPAST)
WHERE uac.SprokID = @SprokId
)
DECLARE @Total INT
SET @Total = ( SELECT
ISNULL(InStock, 0)
FROM SprokInvetory
WHERE id = @SprokId
)
DECLARE @Result INT
IF @Total - @Active > 0
SET @Result = 1
ELSE
SET @Result = 0
RETURN @Result;
END;
答案 0 :(得分:1)
数学已关闭。而不是:
IF @Total - @Active > 0
SET @Result = 1
ELSE
SET @Result = 0
它应该是:
IF @Total - @Active > -1
SET @Result = 1
ELSE
SET @Result = 0
那是因为你的约束函数可以看到你试图添加的行并正在计算它。
答案 1 :(得分:0)
是的,但你的set @ total语句是矛盾的,你的代码中还有几个中断。