尝试从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;//
有帮助吗?

解决方案

  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 Server 之间起作用,因为至少有尝试在同一平台的版本之间保持某种兼容性,但这绝对不适用于移植到<代码> MySQL的

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

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top