使用游标与 2 个表插入行
Use cursor for with 2 tables to insert rows
我有 2 个 table:items
和 cost
。
- 在table
items
中,我有旧商品代码和新商品代码
- 在table
cost
中,我有商品代码和价格
我想根据旧项目代码已经存在的成本,在新项目代码的 table 成本中创建新行。
例如:
我希望在 运行 光标位于 cost
table:
后看到这个结果
我尝试 运行 这个,但它一直 运行ning 并且每行重复 100000 次:
DECLARE @item_code_old nvarchar (50)
DECLARE @item_code_new nvarchar (50)
DECLARE CostCURSOR CURSOR FOR
SELECT item_code_old, item_code_new
FROM item
WHERE company = 'AEW' AND item_code_new IS NOT NULL
OPEN CostCURSOR
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @item_code_old = item_code_old
FROM cost
WHERE company = 'AEW' AND year = 2021
INSERT INTO cost
SELECT
company,
year,
month,
@item_code_new,
unit_cost
FROM
cost
WHERE
company = 'AEW' AND year = 2021
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new
END
CLOSE CostCURSOR
DEALLOCATE CostCURSOR
我错过了什么?
你对变量所做的事情并没有真正意义,你将下一个值提取到 @item_code_old
,但随后在每个循环开始时你几乎随机地为其分配一个值:
SELECT @item_code_old = item_code_old
FROM cost
WHERE company = 'AEW'
AND year = 2021;
那么在插入新成本的时候,根本不用这个变量:
INSERT INTO cost
SELECT company, year, month, @item_code_new, unit_cost
FROM cost
WHERE company = 'AEW'
AND year = 2021;
我猜你不需要重新分配的第一步 @item_code_old
,你确实需要将过滤器应用于插入查询。
话虽如此,这里完全不需要游标(您会发现游标通常是这种情况),您可以通过单个插入来完成此操作,使用如下所示:
INSERT Cost (Company, Year, Month, item_code_old, unit_cost)
SELECT c.company, c.year, c.month, i.item_code_new, c.unit_cost
FROM cost AS c
INNER JOIN Item AS i
ON c.item_code_old = i.item_code_old
WHERE c.company = 'AEW'
AND c.year = 2021
AND i.item_code_new IS NOT NULL;
为了完整起见,您的光标解决方案如下所示,但我要强调这不是一个好方法。游标应该是最后的手段,它可能甚至不值得练习,因为它不是您会发现非常有用的东西。与其练习游标,不如练习尝试找到基于集合的方法,这将更好地利用您的时间。总之,吐槽一下:
DECLARE @item_code_old NVARCHAR(50);
DECLARE @item_code_new NVARCHAR(50);
DECLARE CostCURSOR CURSOR LOCAL FAST_FORWARD FOR
SELECT item_code_old, item_code_new
FROM item
WHERE company = 'AEW'
AND item_code_new IS NOT NULL;
OPEN CostCURSOR;
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new;
WHILE(@@FETCH_STATUS = 0)
BEGIN
INSERT INTO cost (Company, Year, Month, Item_Code_Old, unit_cost)
SELECT company, year, month, @item_code_new, unit_cost
FROM cost
WHERE company = 'AEW'
AND year = 2021
AND item_code_old = @item_code_old;
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new;
END;
CLOSE CostCURSOR;
DEALLOCATE CostCURSOR;
我有 2 个 table:items
和 cost
。
- 在table
items
中,我有旧商品代码和新商品代码 - 在table
cost
中,我有商品代码和价格
我想根据旧项目代码已经存在的成本,在新项目代码的 table 成本中创建新行。
例如:
我希望在 运行 光标位于 cost
table:
我尝试 运行 这个,但它一直 运行ning 并且每行重复 100000 次:
DECLARE @item_code_old nvarchar (50)
DECLARE @item_code_new nvarchar (50)
DECLARE CostCURSOR CURSOR FOR
SELECT item_code_old, item_code_new
FROM item
WHERE company = 'AEW' AND item_code_new IS NOT NULL
OPEN CostCURSOR
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @item_code_old = item_code_old
FROM cost
WHERE company = 'AEW' AND year = 2021
INSERT INTO cost
SELECT
company,
year,
month,
@item_code_new,
unit_cost
FROM
cost
WHERE
company = 'AEW' AND year = 2021
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new
END
CLOSE CostCURSOR
DEALLOCATE CostCURSOR
我错过了什么?
你对变量所做的事情并没有真正意义,你将下一个值提取到 @item_code_old
,但随后在每个循环开始时你几乎随机地为其分配一个值:
SELECT @item_code_old = item_code_old
FROM cost
WHERE company = 'AEW'
AND year = 2021;
那么在插入新成本的时候,根本不用这个变量:
INSERT INTO cost
SELECT company, year, month, @item_code_new, unit_cost
FROM cost
WHERE company = 'AEW'
AND year = 2021;
我猜你不需要重新分配的第一步 @item_code_old
,你确实需要将过滤器应用于插入查询。
话虽如此,这里完全不需要游标(您会发现游标通常是这种情况),您可以通过单个插入来完成此操作,使用如下所示:
INSERT Cost (Company, Year, Month, item_code_old, unit_cost)
SELECT c.company, c.year, c.month, i.item_code_new, c.unit_cost
FROM cost AS c
INNER JOIN Item AS i
ON c.item_code_old = i.item_code_old
WHERE c.company = 'AEW'
AND c.year = 2021
AND i.item_code_new IS NOT NULL;
为了完整起见,您的光标解决方案如下所示,但我要强调这不是一个好方法。游标应该是最后的手段,它可能甚至不值得练习,因为它不是您会发现非常有用的东西。与其练习游标,不如练习尝试找到基于集合的方法,这将更好地利用您的时间。总之,吐槽一下:
DECLARE @item_code_old NVARCHAR(50);
DECLARE @item_code_new NVARCHAR(50);
DECLARE CostCURSOR CURSOR LOCAL FAST_FORWARD FOR
SELECT item_code_old, item_code_new
FROM item
WHERE company = 'AEW'
AND item_code_new IS NOT NULL;
OPEN CostCURSOR;
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new;
WHILE(@@FETCH_STATUS = 0)
BEGIN
INSERT INTO cost (Company, Year, Month, Item_Code_Old, unit_cost)
SELECT company, year, month, @item_code_new, unit_cost
FROM cost
WHERE company = 'AEW'
AND year = 2021
AND item_code_old = @item_code_old;
FETCH NEXT FROM CostCURSOR INTO @item_code_old, @item_code_new;
END;
CLOSE CostCURSOR;
DEALLOCATE CostCURSOR;