使用表参数插入语句时,基于上一行插入值

时间:2017-07-30 20:13:10

标签: sql sql-server

在使用表类型参数插入记录时,我尝试使用条件更新基于前一行的列值。

ALTER PROCEDURE [dbo].[Crud_StockTransaction]
    (@p_StockTransaction UDT_StockTransaction READONLY)   -- table-valued parameter
AS
BEGIN
    INSERT INTO StockTransaction (TransactionType, TransactionId, TransactionItemId, OpeningQuantity, ClosingQuantity)
        SELECT 
            TransactionType, TransactionId, TransactionItemId,
            (SELECT TOP 1 ISNULL(ClosingQuantity, 0)
             FROM StockTransaction 
             WHERE TransactionType = A.TransactionType AND TransactionItemId = A.TransactionItemId),
            --OpeningQuantity,
            CASE A.TransactionType 
               WHEN 1 
                  THEN ((SELECT TOP 1 ISNULL(ClosingQuantity, 0) 
                         FROM StockTransaction 
                         WHERE TransactionType = A.TransactionType 
                           AND TransactionItemId = A.TransactionItemId) + A.Quantity)
                WHEN 2 
                   THEN ((SELECT TOP 1 ISNULL(ClosingQuantity, 0) 
                          FROM StockTransaction 
                          WHERE TransactionType = A.TransactionType 
                            AND TransactionItemId = A.TransactionItemId) - A.Quantity)
            END,
            --ClosingQuantity,
        FROM 
            @p_StockTransaction

END

这似乎很复杂,有没有更好的方法来做同样的事情?

1 个答案:

答案 0 :(得分:3)

您的ORDER BY需要TOP 1才能选择正确的行。您也不需要重复三次表达式。

您可以使用

INSERT INTO StockTransaction
            (TransactionType,
             TransactionId,
             TransactionItemId,
             OpeningQuantity,
             ClosingQuantity)
SELECT TransactionType,
       TransactionId,
       TransactionItemId,
       OpeningQuantity,
       CASE A.TransactionType
         WHEN 1
           THEN OpeningQuantity + A.Quantity
         WHEN 2
           THEN OpeningQuantity - A.Quantity
       END AS ClosingQuantity
FROM   @p_StockTransaction A
       CROSS APPLY (SELECT ISNULL((SELECT TOP 1 ClosingQuantity
                                   FROM   StockTransaction ST
                                   WHERE  ST.TransactionType = A.TransactionType
                                          AND ST.TransactionItemId = A.TransactionItemId
                                   ORDER  BY ST.TransactionId DESC /*??*/), 0)) CA(OpeningQuantity) 

您还应该考虑并发性。如果可以为同一个TransactionType, TransactionItemId并行调用它,则需要额外的锁定提示(并且您需要确保在输入TVP中没有重复项)