2015-06-11 2 views
3

Я развиваю эту хранимую процедуру SQL Server 2012.Как обновить N строк, когда N находится в из (выберите N от @myVar)

Хранимая процедура обновления Quantity строки в EXTERNAL_CODES таблице для каждой строки в параметре @newBatches. Это похоже на цикл, мне нужно будет создать новую строку в таблице BATCHES для каждой строки в параметре @newBatches.

И затем, я должен обновить Quantity строк в EXTERNAL_CODES стол с каждым batchId создан.

CREATE PROCEDURE [dbo].[CreateBatchAndKeepExternalCodes] 
     @newBatches as dbo.CreateBatchList READONLY, 
     @productId int 
AS 
    set nocount on; 

    declare @lowestCodeLevel tinyint; 

-- ======== VALIDATION ========== 
    if ((select count(name) from @newBatches) = 0) 
     return -112; 

-- ====== CODE ======== 

    -- Get lowest aggregation level. 
    set @lowestCodeLevel = 
     (select min(c.application_code) 
      from CHINA_CODES_HEADER c, PRODUCTS p 
      where p.Id = @productId and c.DRUG_TEN_SEATS = p.PRODUCT_CODE); 

    begin transaction; 

     insert into BATCHES (PRODUCT_ID, NAME, CREATED) 
      select @productId, Name, CAST(SYSDATETIMEOFFSET() as nvarchar(50)) 
       from @newBatches; 

     update top(t.Quantity) EXTERNAL_CODES 
      set BATCH_ID = (select ID from BATCHES where NAME = t.Name) 
      , USED = 1 
     from (select Name, Quantity from @newBatches) t 
     where PRODUCT_ID = @productId and CODE_LEVEL = @lowestCodeLevel; 

    commit transaction; 

RETURN 0 

Я получаю ошибку на update:

update top(t.Quantity) EXTERNAL_CODES 
    set BATCH_ID = (select ID from BATCHES where NAME = t.Name) 
    , USED = 1 
from (select Name, Quantity from @newBatches) t 
where PRODUCT_ID = @productId and CODE_LEVEL = @lowestCodeLevel; 

Ошибка здесь: update top(t.Quantity). Он не может найти t.Quantity.

dbo.CreateBatchList является:

CREATE TYPE [dbo].[CreateBatchList] AS TABLE 
(
    Name nVARCHAR(20), 
    Quantity int 
) 

Моя проблема заключается в том, что я не могу установить, чтобы обновить Quantity строки. Есть идеи?

Ошибка (или предупреждение) сообщение:

SQL71005: Ссылка на t.Quantity колонке не может быть решена.

Возможно, я мог бы использовать MERGE.

+1

Я думаю, проблема заключается в том, что 't.Quantity' потенциально различается для каждой строки в предложении from. кроме того, нет смысла «топ» без «порядка». –

+0

Сообщение об ошибке (или предупреждении): SQL71005: ссылка на столбец t.Quantity не может быть разрешена. – VansFannel

+1

, потому что это часть предложения from, что означает, что это решение для каждой строки в обновлении. число в 'top (number)' должно быть числом, которое принято ** перед ** оператором обновления ... –

ответ

0

Ваше заявление об обновлении довольно запутанно. Если, например, таблица @newBatches имеет несколько строк, то вы говорите, выбираете все Quantity от @newBatches в Top?

В любом случае, я думаю, что решение заключается в использовании цикла для использования каждой строки от @newBatches для обновления. Я изменил ваш код, чтобы проверить его на моей стороне, и заменил все таблицы на переменные таблицы. Вы можете найти это полезным.

Но все же без какой-либо статьи Order By и без знания фактической бизнес-логики я не могу сказать, что это решение является правильным.

DECLARE @productID int; 
DECLARE @lowestCodeLevel int; 

DECLARE @EXTERNAL_CODES table(BATCH_ID varchar(100), USED bit, PRODUCT_ID int, CODE_LEVEL int); 
DECLARE @BATCHES table(ID int, NAME varchar(100)); 
DECLARE @newBatches table(Name nVARCHAR(20), Quantity int); 



-- we don't know at this point whether @newBatches has some column 
-- through which we can uniquely identify a row 
-- that is why we are creating this new table in which we have Row_ID column 
-- through which we can extract each line 
DECLARE @newBatchesWithRowID table(Row_ID int not null identity, Name nVarchar(20), Quantity int); 

INSERT INTO @newBatchesWithRowID(Name, Quantity) 
    SELECT Name, Quantity 
    FROM @newBatches; 

DECLARE @prvRow_ID int; 

-- loop to iterate in @newBatchesWithRowID table 
WHILE(1 = 1) 
Begin 
    DECLARE @row_ID int = NULL; 
    DECLARE @Name varchar(100); 
    DECLARE @Quantity int; 

    SELECT TOP 1 @row_ID = Row_ID 
      , @Quantity = Quantity 
      , @Name = Name 
    FROM @newBatchesWithRowID 
    WHERE Row_ID > @prvRow_ID OR @prvRow_ID IS NULL 
    ORDER BY Row_ID; 
    If @row_ID IS NULL Break; 
    SET @prvRow_ID = @row_ID; 

    update top(@Quantity) @EXTERNAL_CODES 
     set BATCH_ID = (select ID from @BATCHES where NAME = @Name) 
     , USED = 1 
    where PRODUCT_ID = @productId and CODE_LEVEL = @lowestCodeLevel; 
END 
Смежные вопросы