2010-11-01 37 views
0

我有一个使用嵌套集模型的分层MySQL表设置。我创建了一个存储过程,允许我删除一个组织。MySQL错误2014-命令不同步 - 当试图调用连续存储的procs时

当我尝试进行连续调用的存储过程,我得到以下错误指的是第二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 ; 

为什么第二个命令是失败的?在第一个CALL命令提交之前,MySQL是否尝试执行第二个CALL命令?在调用第二个之前,我能强制第一个完全执行吗?

编辑:组织表使用的InnoDB

编辑:试图消除START TRANSACTION;和COMMIT;但我仍然得到相同的错误

+0

您使用的是什么版本的MySQL? – 2010-11-01 20:23:14

+0

MySQL版本5.1.41 – 2010-11-01 20:24:33

回答

0

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

2

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

我的建议是在程序中声明局部变量,并使用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 ; 
0

我在寻找的答案也一样,据我所知它与由第一SP返回的记录。您必须“读取”记录集将其清空,然后再创建一个新的CALL。

相关问题