1

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

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

但我不想改变任何过于激烈的东西,因为现在我只是想转换数据库。我稍后会回去优化这些东西。这是 SP:编辑:我从这个示例中删除了所有与错误无关的代码。另外,我今天在网上看到了这个,看来我不是唯一一个遇到这个问题的人。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;//
4

1 回答 1

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 Server并且MySQL截然不同的平台。

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

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

它可能会SQL ServerMySQL.

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

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

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

于 2009-06-16T09:42:24.913 回答