2016-11-14 3 views
0

У меня есть хранимая процедура, которая получает от пользователя два параметра, а именно: referenceNumber и destinationLocation, где 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 

То, что я хочу добиться того, чтобы навалом вставить все эти записи в соответствующие места назначения и уточнения количества, если это место было тот же элемент, прежде чем руки.

Таким образом, я сделал эту хранимую процедуру, которая делает серию вставки, обновления и падения:

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 есть только одна строка (позиция) в одном referenceNumber но воны 't правильно вставить, если имеется несколько записей.

Таким образом, я попытался использовать курсор, но он вставляет дубликаты идентификаторов продуктов в DestinationLocation.

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, то он будет добавлять их вместе. Однако при использовании курсора он вставляет тот же «ProductID» из tblStockMove, что приводит к дублированию идентификаторов в DcMo – 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 
Смежные вопросы