帮我解决这个 MySql 游标代码

发布于 2024-07-25 06:15:05 字数 820 浏览 4 评论 0原文

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

Trying to migrate from MSSQL to MySQL. This Stored Proc is creating a temp table for some columns from a permanent table then using a cursor to update each record's RandNum column with a random number and selects the dataset. As I'm writing this I thought that I could bypass the cursor and just...

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

But i dont want to change anything too drastic, because right now I'm just trying to convert the DB. I will go back and optimize this stuff later. Here's the SP: EDIT: I removed all of the code from this example that has nothing to do with the error. Also, I saw this online today and it seems that I'm not the only one who is having this issue. MySQL does not like the syntax of my cursor declaration. Any Ideas?

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;//

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情徒 2024-08-01 06:15:05
  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 中,变量具有会话作用域。

  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;

You are using unitialized session variable @cursor_id instead of procedure-declared variable cursor_id

Rewrite as follows:

  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;

or even better, just get rid of your temporary table at all, as you suggested in the first place.


As for this statement:

But i dont want to change anything too drastic, because right now I'm just trying to convert the DB. I will go back and optimize this stuff later.

SQL Server and MySQL are vastly different platforms.

You've already changed everything too drastic when decided to switch.

In most cases you can't just copy your old code and hammer it to MySQL.

It would possibly work between several versions of SQL Server, since at least there are attempts to maintain some kind of compatibility between the versions of same platform, but this definitely won't work for porting to MySQL.

What I would do is take every piece of your code and make sure it produces the same results as the old code did, using methods as simple and predictable as possible.

In your case, the @cursor_id variable could be initialized earlier in the code and its value could be used by the stored procedure, which would lead to any kind of unexpected behaviour.

This is because in SQL Server the variables have batch scope, while in MySQL they have session scope.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文