SQL Server Cursor重复问题

时间:2017-07-03 02:04:41

标签: sql sql-server

关于SQL-Server的问题我有一个包含Id的表1 2 3 4 5我想创建一个存储过程,通过传递一个参数来执行对另一个表的插入,所以基本上结果会像像那样

1 134 2 134 3 134 4 134 5 134

我知道通过光标做到了。



DECLARE @LocationID Int -- @LocationID is what I'm passing to the store proc
DECLARE cursorName CURSOR -- Declare cursor

FOR
 
Select ModuleID FROM Modules 
Where  Active = 1
 
OPEN cursorName 

FETCH NEXT FROM cursorName 
 
   INTO @LocationID 
 

WHILE @@FETCH_STATUS = 0
 
BEGIN
	Insert INTO PostModules(LocationID,ModuleID) 
	Select @LocationID,ModuleID from Modules
 
   FETCH NEXT FROM cursorName
 
   INTO @LocationID
 


END
 
CLOSE cursorName -- close the cursor

DEALLOCATE cursorName -- Deallocate the cursor




我在理论上得到的结果太多我只能得到:

模块表包含5个ID @LocationID = 134 - 已传入商店程序 结果:

1 134 | 2 134 | 3 134 | 4 134 | 5 134

1 个答案:

答案 0 :(得分:1)

如前所述,您不需要光标来实现这一目标。基于集合的操作总是比通过逐行操作接近数据集更快。

这是一个可以达到预期效果的更新声明:

UPDATE 
    PostModules
SET 
    LocationID = 123
WHERE 
    EXISTS (
        SELECT 1 FROM Modules b WHERE ACTIVE = 1 AND PostModules.ModuleID = b.id)

这里有一些示例代码,用于创建表并使用示例数据填充它们:

CREATE TABLE Modules (id int, active bit)

INSERT INTO Modules VALUES (1,1), (2,1), (3,1), (4, 1), (5, 1), (6, 0), (7, 0), (8, 1);

请注意,1-5和8都是活动的,但6和7不是。

CREATE TABLE PostModules(LocationID int ,ModuleID int);

INSERT INTO PostModules Values 
(0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8);

我在这里为每个ModuleID添加默认值。如果没有匹配的moduleID,则不会发生任何事情。

UPDATE PostModules
SET LocationID = 123
WHERE EXISTS (SELECT 1 FROM Modules b WHERE ACTIVE = 1 AND PostModules.ModuleID = b.id)

SELECT * FROM PostModules

输出:

LocationID  ModuleID
123 1
123 2
123 3
123 4
123 5
0   6
0   7
123 8

请记住,为了使其正常工作,PostModules必须为每个活动的ModuleID都有一个值。如果您有上述脚本,可以通过添加ModuleID 9来验证这一点:

INSERT INTO Modules VALUES (9,1)

重新运行UPDATE语句将产生与之前完全相同的结果,因为9不会作为PostModules表中的ModuleID存在。

理论上,你的代码实际上应该也可以运行。我不确定你为什么会看到5个结果。如果您仍然很好奇,请向我们展示光标返回的实际结果。