我正在SQL Server 2012上开发此存储过程。
对于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
。
答案 0 :(得分: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