SQL Server数据库未通过查询更新

时间:2014-07-16 11:16:45

标签: sql-server

我有以下代码:

/************************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是否有正确的记录要更新,我无法看到它还有什么。任何帮助将不胜感激。

4 个答案:

答案 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