[英]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.