帮我解决这个MySql游标代码

时间:2009-06-16 09:37:08

标签: mysql stored-procedures cursor fetch

尝试从MSSQL迁移到MySQL。此存储过程正在为永久表中的某些列创建临时表,然后使用游标以随机数更新每个记录的RandNum列并选择数据集。在我写这篇文章的时候,我以为我可以绕过光标而只是......

SELECT Id, Title, DateStart, Rand() FROM cms_News;

但是我不想改变任何过于激烈的东西,因为现在我只是想转换数据库。我稍后会回过头来优化这些东西。这是SP:编辑:我删除了此示例中与错误无关的所有代码。另外,我今天在网上看到了this,似乎我不是唯一一个遇到这个问题的人。 MySQL不喜欢我的游标声明的语法。任何想法?

DELIMITER ;//

DROP PROCEDURE IF EXISTS `cms_NewsSelectMainPageNews`;//
CREATE PROCEDURE `cms_NewsSelectMainPageNews`
()
BEGIN
  CREATE TEMPORARY TABLE tempNews
  (
    Id int NOT NULL, 
    Title nvarchar(250),
    DateStart datetime,
    RandNum float NULL
  );

  DECLARE Randomizer CURSOR
      FOR SELECT Id FROM tempNews;
END;//

1 个答案:

答案 0 :(得分:0)

  REPEAT
    FETCH Randomizer INTO cursor_id;
    IF NOT done THEN
      UPDATE tempNews SET RandNum = rand();
       WHERE id = @cursor_id;
    END IF;
  UNTIL done END REPEAT;

您正在使用单元化会话变量@cursor_id而不是过程声明的变量cursor_id

重写如下:

  REPEAT
    FETCH Randomizer INTO cursor_id;
    IF NOT done THEN
      UPDATE tempNews SET RandNum = rand();
       WHERE id = cursor_id;
    END IF;
  UNTIL done END REPEAT;

甚至更好,根本就是你的临时表,正如你在第一时间所建议的那样。


至于这句话:

  

但是我不想改变任何过于激烈的东西,因为现在我只是想转换数据库。我稍后会回过头来优化这些东西。

SQL ServerMySQL 非常不同的平台。

当你决定转换时,你已经彻底改变了一切。

在大多数情况下,您不能只复制旧代码并将其锤入MySQL

它可能在几个版本的SQL Server之间起作用,因为至少有尝试在同一平台的版本之间保持某种兼容性,但这绝对不适用于移植到{{1} }。

我要做的是拿走你的每一段代码并确保它产生与旧代码相同的结果,使用方法尽可能简单和可预测

在您的情况下,MySQL变量可以在代码中更早地初始化,并且其值可以由存储过程使用,这将导致任何类型的意外行为。

这是因为在@cursor_id中变量具有批量范围,而在SQL Server中它们具有会话范围。