MySQL 错误 2014 - 命令不同步 - 尝试调用连续存储过程时

发布于 2024-09-30 08:16:12 字数 1172 浏览 1 评论 0原文

我有一个使用嵌套集模型的分层 MySQL 表设置。我创建了一个存储过程,它允许我删除组织。

当我尝试连续调用存储过程时,出现以下涉及第二个 CALL 命令的错误:

2014 - 命令不同步;您现在无法运行此命令

这是我正在运行的 SQL:

SELECT @id := id, 
       @parent_id := parent_id 
  FROM organization 
 WHERE name = 'TESTDEAL';

CALL deleteOrg(@id);
CALL deleteOrg(@parent_id);

这是我的存储过程:

DELIMITER $$

CREATE PROCEDURE deleteOrg(IN IN_ID INT)

MODIFIES SQL DATA

BEGIN 

    START TRANSACTION;

    SELECT @org_id := id, 
           @myLeft := lft, 
           @myRight := rgt,  
           @myWidth := rgt - lft + 1 
      FROM organization 
     WHERE id = IN_ID;

    # delete statements for removing roles and other dependencies

    DELETE FROM organization 
     WHERE id = @org_id;

    UPDATE organization 
       SET rgt = rgt - @myWidth 
     WHERE rgt > @myRight;

    UPDATE organization 
       SET lft = lft - @myWidth 
     WHERE lft > @myRight;

    COMMIT;

END;
$$

DELIMITER ;

为什么第二个命令会失败? MySQL 是否在第一个 CALL 命令提交之前尝试执行第二个 CALL 命令?有没有办法在调用第二个之前强制第一个完全执行?

编辑:组织表正在使用 InnoDB

编辑:尝试删除 START TRANSACTION;并提交;但我仍然遇到同样的错误

I have a hierarchical MySQL table setup using the Nested Set model. I have created a stored proc which allows me to delete an organization.

When I try making consecutive calls to the stored proc, I get the following error referring to the second CALL command:

2014 - Commands out of sync; you can't run this command now

Here is the SQL I am running:

SELECT @id := id, 
       @parent_id := parent_id 
  FROM organization 
 WHERE name = 'TESTDEAL';

CALL deleteOrg(@id);
CALL deleteOrg(@parent_id);

And here is my Stored Procedure:

DELIMITER $

CREATE PROCEDURE deleteOrg(IN IN_ID INT)

MODIFIES SQL DATA

BEGIN 

    START TRANSACTION;

    SELECT @org_id := id, 
           @myLeft := lft, 
           @myRight := rgt,  
           @myWidth := rgt - lft + 1 
      FROM organization 
     WHERE id = IN_ID;

    # delete statements for removing roles and other dependencies

    DELETE FROM organization 
     WHERE id = @org_id;

    UPDATE organization 
       SET rgt = rgt - @myWidth 
     WHERE rgt > @myRight;

    UPDATE organization 
       SET lft = lft - @myWidth 
     WHERE lft > @myRight;

    COMMIT;

END;
$

DELIMITER ;

Why would the second command be failing? Is MySQL trying to execute the second CALL command before the first one has been committed? Is there a way I can force the first one to fully execute before calling the second?

EDIT: organization table is using InnoDB

EDIT: Tried removing START TRANSACTION; and COMMIT; but am still getting same error

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

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

发布评论

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

评论(3

一向肩并 2024-10-07 08:16:13

该错误似乎仅在从 phpMyAdmin 导入 SQL 脚本时发生。从命令行导入脚本或使用命令行不会导致错误。我假设这个错误与 phpMyAdmin 而不是 MySQL 有关。 (我还看到 phpMyAdmin 与存储过程相关的其他奇怪行为 - 我正在使用 phpMyAdmin v3.3.2)

The error only seems to be occurring when importing an SQL script from phpMyAdmin. Importing the script from the command line or using the command line does not result in an error. I'm assuming this error has to do with phpMyAdmin and not MySQL. (I have also seen other strange behaviour from phpMyAdmin relating to Stored Procedures - I am using phpMyAdmin v3.3.2)

寄离 2024-10-07 08:16:13

我也在寻找答案,据我所知,它与第一个 SP 返回的记录集有关。您必须“读取”记录集以清空它,然后进行新的 CALL。

I'm looking for the answer too, AFAIK it's related to the recordset returned by the first SP. You must 'read' the recordset to empty it and then make a new CALL.

无人问我粥可暖 2024-10-07 08:16:12

我猜这可能与您分配变量的方式有关。

我的建议是在过程中声明局部变量,并使用 SELECT...INTO 分配它们。一般来说,这是一个很好的做法,可能会帮助您解决问题。

您的程序如下所示:

DELIMITER $

DROP PROCEDURE IF EXISTS deleteOrg $

CREATE PROCEDURE deleteOrg(IN IN_ID INT)

MODIFIES SQL DATA

BEGIN 
  DECLARE V_ORG_ID INT;
  DECLARE V_MY_LEFT INT;
  DECLARE V_MY_RIGHT INT;
  DECLARE V_MY_WIDTH INT;

    START TRANSACTION;

    SELECT id, 
           lft, 
           rgt, 
           rgt - lft + 1
      into V_ORG_ID, 
           V_MY_LEFT, 
           V_MY_RIGHT,  
           V_MY_WIDTH
      FROM organization 
     WHERE id = IN_ID;

    -- delete statements for removing roles and other dependencies

    DELETE FROM organization 
     WHERE id = V_ORG_ID;

    UPDATE organization 
       SET rgt = rgt - V_MY_WIDTH 
     WHERE rgt > V_MY_RIGHT;

    UPDATE organization 
       SET lft = lft - V_MY_WIDTH 
     WHERE lft > V_MY_LEFT;

COMMIT;

END;
$

DELIMITER ;

I'm guessing this might have something to do with the way you are assigning your variables.

My advice is to declare local variables inside your procedure, and to assign them using SELECT...INTO. This is a good practice in general, and may help you with your problem.

Here's what your procedure would look like:

DELIMITER $

DROP PROCEDURE IF EXISTS deleteOrg $

CREATE PROCEDURE deleteOrg(IN IN_ID INT)

MODIFIES SQL DATA

BEGIN 
  DECLARE V_ORG_ID INT;
  DECLARE V_MY_LEFT INT;
  DECLARE V_MY_RIGHT INT;
  DECLARE V_MY_WIDTH INT;

    START TRANSACTION;

    SELECT id, 
           lft, 
           rgt, 
           rgt - lft + 1
      into V_ORG_ID, 
           V_MY_LEFT, 
           V_MY_RIGHT,  
           V_MY_WIDTH
      FROM organization 
     WHERE id = IN_ID;

    -- delete statements for removing roles and other dependencies

    DELETE FROM organization 
     WHERE id = V_ORG_ID;

    UPDATE organization 
       SET rgt = rgt - V_MY_WIDTH 
     WHERE rgt > V_MY_RIGHT;

    UPDATE organization 
       SET lft = lft - V_MY_WIDTH 
     WHERE lft > V_MY_LEFT;

COMMIT;

END;
$

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