2016-11-14 130 views
0

我有一个存储过程,它从用户获取两个参数,即referenceNumberdestinationLocation,其中referenceNumber是该行的唯一标识符,而destinationLocation是请求的物品将被传送到的位置。请参阅下表tblStockMove每行返回执行存储过程?

deliveryID | ProductID | SourceLocation | DestinationLocation | Quantity | deliveryStart | deliveryEnd | ReferenceNumber | Status | Requestor | Receiver | ControlNumber | MoveType | ProductCode 
13   | 1   | WAREHOUSE | Burger Queen  | 5  | 2016-11-14 | NULL  | CTRL_MULTI01 | PENDING| john.doe | NULL  | CTRL_MULTI01 | MULTIPLE | 19000207 
14   | 1   | WAREHOUSE | DcMo    | 4  | 2016-11-14 | NULL  | CTRL_MULTI01 | PENDING| john.doe | NULL  | CTRL_MULTI01 | MULTIPLE | 19000207 
15   | 1   | WAREHOUSE | Strapbucks   | 10  | 2016-11-14 | NULL  | CTRL_MULTI01 | PENDING| john.doe | NULL  | CTRL_MULTI01 | MULTIPLE | 19000207 
16   | 2   | WAREHOUSE | DcMo    | 6  | 2016-11-14 | NULL  | CTRL_MULTI01 | PENDING| john.doe | NULL  | CTRL_MULTI01 | MULTIPLE | 19000209 

我想实现的是批量插入所有这些记录到各自的目标位置和更新的数量,如果该位置前手有同样的项目。在一个referenceNumber但韩元

CREATE procedure updateTBLStock 
    @referenceNumber nvarchar(50), 
    @destinationLocation nvarchar(50) 
as begin 
    --1) insert non existing items to a temporary table 
     INSERT INTO tblTempStockList 
     SELECT b.ProductID, a.ProductName, a.ProductCode, b.Quantity, a.UnitOfMeasure, 
     a.Provider, a.Category, a.ExpirationDate, b.DestinationLocation, b.ReferenceNumber 
      FROM tblStockMove b 
      inner join tblProducts_warehouse a on b.ProductCode = a.ProductCode 
      where b.ReferenceNumber = @referenceNumber 
      and NOT EXISTS (Select a.ProductCode from tblProducts_establishments a 
      where b.ProductCode = a.ProductCode 
      and a.Location = @destinationLocation 
      and b.ReferenceNumber = @referenceNumber 
      and b.MoveType = 'MULTIPLE') 

    --2) update items' quantity if they already exist in the destination location 
      UPDATE tblProducts_establishments 
      SET Quantity = a.Quantity + b.Quantity 
      from tblProducts_establishments a 
      left join tblStockMove b 
      on a.ProductCode = b.ProductCode 
      where b.ReferenceNumber = @referenceNumber 
      and b.MoveType = 'MULTIPLE' 
      and a.Location = @destinationLocation 
      and EXISTS (Select a.ProductCode from tblProducts_establishments a 
      where b.ProductCode = a.ProductCode and a.Location = @destinationLocation 
      and b.ReferenceNumber = @referenceNumber and b.MoveType = 'MULTIPLE')  

    --3) Insert the row from the temporary table to the main table 

      INSERT INTO tblProducts_establishments (ProductID, ProductName, ProductCode, Quantity, UnitOfMeasure, Date, Provider, Category, ExpirationDate, Status, Location) 
      SELECT ProductID, ProductName, ProductCode, Quantity, UnitOfMeasure, getdate(), Provider, Category, ExpirationDate, null, Location FROM tblTempStockList where ReferenceNumber = @referenceNumber and Location = @destinationLocation 

    --4) Empty the temporary table 
      DELETE FROM tblTempStockList where ReferenceNumber = @referenceNumber and Location = @destinationLocation 

该查询运行正常IF只有一个行(项):

因此,我做了这个存储过程,而做了一系列的插入,更新和降如果有多个条目,则不能正确插入。

所以我尝试使用游标,但它会为每个DestinationLocation插入重复的ProductID。

declare @destinationLocation nvarchar(50) 
declare @referenceNumber nvarchar(50) 

declare cur CURSOR LOCAL for 
    select DestinationLocation, ReferenceNumber from tblStockMove where ControlNumber = 'CTRL_MULTI01' 
open cur 

fetch next from cur into @destinationLocation, @referenceNumber 

while @@FETCH_STATUS = 0 BEGIN 

    execute updateTBLStock @referenceNumber, @destinationLocation 

    fetch next from cur into @destinationLocation, @destinationLocation 
END 

close cur 
deallocate cur 

我的问题是,我怎样才能成功地使用上面的光标调用存储过程?如何从光标传递我的存储过程需要的两个变量?

+0

你'CURSOR'是已经在做了。你目前的代码有什么问题? –

+0

我的SP应该更新特定机构中现有产品的数量,例如,如果ProductID 1存在于DcMo中,并且tblStockMove有5,那么它会将它们加在一起。然而,在使用游标时,它会从tblStockMove插入相同的'ProductID',导致DcMo中出现重复的ID – Saudate

回答

0

通过创建表作为 型像

CREATE TYPE dbo.TBLStockType AS TABLE 
(
    referenceNumber nvarchar(50), 
    destinationLocation nvarchar(50) 
) 

您通过参数表类型变量GO

那么用户该类型在你的程序中像

CREATE procedure updateTBLStock 
@referenceNumber TBLStockType READONLY, 
@destinationLocation TBLStockType READONLY 
as begin 

    --your code here 
end 

利用这一点,你可以一次传递多个参数。 传递你的参数如下

DECLARE @StockType AS TBLStockType

INSERT INTO @StockType 
SELECT 'CTRL_MULTI01','DcMo' 
union all 
select 'CTRL_MULTI01','DcMo' 

--then execute proc 

EXEC updateTBLStock @StockType