我有以下代码:
/************************Cursors and Variables**********************/
DECLARE @id varchar(15), @type varchar(15), @new_display_order int;
--gets the areas in correct order
DECLARE @c_get_objects CURSOR
SET @c_get_objects = CURSOR FOR
SELECT o.id
FROM t_object o
where o.type = @type
order by id;
/**************End cursor and variable declarations*****************/
SET @type = 'Generic'
OPEN @c_get_objects
FETCH NEXT FROM @c_get_objects
INTO @id;
SET @new_display_order = 30;
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE t_object
SET display_order = @new_display_order
WHERE id = @id;
SET @new_display_order = @new_display_order + 10;
END
CLOSE @c_get_objects;
DEALLOCATE @c_get_objects;
当我在SQL Server Management Studio中运行它时,我收到一条消息,说明命令已成功完成。但是,当我查询数据库时,似乎没有发生更新。我已经仔细检查过@c_get_objects是否有正确的记录要更新,我无法看到它还有什么。任何帮助将不胜感激。
答案 0 :(得分:3)
您必须在声明光标之前设置@Type值:
SET @type = 'Generic'
DECLARE @c_get_objects CURSOR
SET @c_get_objects = CURSOR FOR
SELECT o.id
FROM t_object o
where o.type = @type
order by id;
答案 1 :(得分:3)
您需要在声明光标之前设置@Type
,或者这是您的实际查询并且@Type
被硬编码为generic
,只需将其直接放在光标中:
SET @c_get_objects = CURSOR FOR
SELECT o.id
FROM t_object o
where o.type = 'Generic'
order by id;
但即使你这样做,你的代码也会产生一个infinte循环。你永远不会将光标推进循环内部。我希望看到类似的东西:
WHILE @@FETCH_STATUS = 0
BEGIN
UPDATE t_object
SET display_order = @new_display_order
WHERE id = @id;
SET @new_display_order = @new_display_order + 10;
FETCH NEXT FROM @c_get_objects INTO @id;
END
虽然它值得,但根本不需要使用光标,建议不要使用光标。
WITH CTE AS
( SELECT o.id ,
NewOrder = 20 + (10 * ROW_NUMBER() OVER(ORDER BY o.id))
FROM t_object o
WHERE o.type = @type
)
UPDATE CTE
SET display_order = NewOrder;
对于每个display_order
,这将为10
增加ID
做同样的工作,但不使用繁琐的循环,而是使用分析函数ROW_NUMBER()
(从30)。
答案 2 :(得分:1)
在声明光标之前设置@type ...
答案 3 :(得分:0)
您可以尝试以下操作代替Cursor
:
DECLARE @new_display_order INT = 30
UPDATE T
SET T.display_order = O.new_display_order
FROM t_object AS T INNER JOIN
(SELECT ID, (ROW_NUMBER() OVER (ORDER BY ID) * 10) + @new_display_order AS new_display_order
FROM t_object) AS O ON T.ID = O.ID
WHERE o.type = @type