【问题标题】:Help me out with this MySql cursor code帮我解决这个 MySql 游标代码
【发布时间】:2009-06-16 09:37:07
【问题描述】:

尝试从 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;//

【问题讨论】:

    标签: mysql stored-procedures cursor fetch


    【解决方案1】:
      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 的多个版本之间工作,因为至少有尝试在同一平台的版本之间保持某种兼容性,但这绝对不适用于移植到MySQL

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

    在您的情况下,@cursor_id 变量可以在代码的早期初始化,并且它的值可以被存储过程使用,这会导致任何类型的意外行为。

    这是因为在SQL Server 中的变量具有批处理范围,而在MySQL 中它们具有会话范围。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多