简体   繁体   English

SQL Server游标重复问题

[英]SQL Server Cursor duplicates issue

Question about SQL-Server I have a Table that holds Id's 1 2 3 4 5 and I want to create a store procedure that performs an insert to another table by passing a parameter so essentially the result would like something like that 关于SQL Server的问题我有一个表,该表持有Id的1 2 3 4 5,并且我想创建一个存储过程,该过程通过传递参数来对另一张表执行插入操作,因此从本质上讲,结果类似于

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

I know that there's away in by doing it with cursor. 我知道用游标可以解决问题。

 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 

I'm getting too many results in theory I'm only supposed to get: 从理论上我得到了太多的结果,我只能得到:

Modules Table contains 5 Id's @LocationID = 134 -- Been passed in to the store procedure Results: 模块表包含5个ID的@LocationID = 134-传递给存储过程结果:

1 134 | 1134 | 2 134 | 2134 | 3 134 | 3 134 | 4 134 | 4134 | 5 134 5134

As has been said already, you don't need a cursor to achieve this. 如前所述,您不需要游标即可实现此目的。 Set-based operations are always faster than approaching a dataset by doing a row-by-row operation. 基于集合的操作总是比通过逐行操作来接近数据集更快。

Here's an update statement that will achieve the desired result: 这是一条更新语句,它将实现所需的结果:

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

Here's some sample code that creates the tables and fills them with sample data: 以下是一些示例代码,这些示例代码创建表并用示例数据填充它们:

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);

Notice that 1-5 as well as 8 are active, but 6 and 7 are not. 请注意,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);

I'm adding a default value for every ModuleID here. 我在这里为每个ModuleID添加一个默认值。 If there's no matching moduleID, nothing will happen. 如果没有匹配的moduleID,则不会发生任何事情。

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

SELECT * FROM PostModules

Output: 输出:

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

Keep in mind that in order for this to work, PostModules already has to have a value for every active ModuleID. 请记住,为使此功能正常运行,PostModules必须已经为每个活动的ModuleID设置了一个值。 If you have the above script, you can verify this by adding ModuleID 9: 如果您具有上述脚本,则可以通过添加ModuleID 9来进行验证:

INSERT INTO Modules VALUES (9,1)

Rerunning the UPDATE statement will yield the exact same results as before, because 9 doesn't exist as a ModuleID in the PostModules table. 重新运行UPDATE语句将产生与以前完全相同的结果,因为PostModules表中的ModuleID不存在9。

In theory, your code actually ought to work as well. 从理论上讲,您的代码实际上也应该工作。 I'm not sure why you would be seeing 5 results. 我不确定为什么会看到5个结果。 If you are still curious, please show us the actual results returned by the cursor. 如果您仍然好奇,请向我们显示光标返回的实际结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM