MySQL存储过程给命令行不同的结果



我有一个简单的MySQL存储过程,用于返回给定节点的所有子记录。我的问题是,当我手动输入它返回正确的结果-但是当我将相同的代码放入存储过程时,它只返回父id。

我真的很感激你的指导!

例如-当我调用我的过程(代码如下)时,我得到:

call find_child(1006);
+--------+
| nodeid |
+--------+
|   1006 |
|   1006 |
|   1006 |
|   1006 |
+--------+
4 rows in set (0.01 sec)

BUT -当我剪切和粘贴命令时,我得到了正确的结果集:

mysql> create temporary table KID_TABLE (nodeid INT);
Query OK, 0 rows affected (0.00 sec)
mysql> insert ignore into KID_TABLE (nodeid) select nodeid from CORPORATENODE 
       where parentid in (1006);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0
mysql> select * from KID_TABLE;
+--------+
| nodeid |
+--------+
|   1007 |
|   1008 |
|   1031 |
|   1038 |
+--------+
4 rows in set (0.00 sec)

代码如下:

DELIMITER $$
DROP PROCEDURE IF EXISTS `find_child`$$
CREATE PROCEDURE  `find_child`( IN NodeID INT)
    DETERMINISTIC
BEGIN
declare nid INT;
set nid= NodeID;
create temporary table KID_TABLE (nodeid INT);
insert ignore into KID_TABLE (nodeid) select nodeid 
from CORPORATENODE where parentid in (1006);
select * from KID_TABLE;
drop table KID_TABLE;
END $$
DELIMITER ;

下面是父表

的DDL
    CREATE TABLE  `PARENT` (  
    `NODEID` int(11) NOT NULL AUTO_INCREMENT,  
    `PARENTID` int(11) NOT NULL DEFAULT '0' COMMENT '0 value means top node',  
    `NAME` varchar(50) NOT NULL,  
    PRIMARY KEY (`NODEID`) USING BTREE  
    ) ENGINE=InnoDB;

Mysql将返回您的in变量NodeId在您的select nodeid from CORPORATENODE where parentid in (1006);

将变量改为in_NodeID

DELIMITER $$
DROP PROCEDURE IF EXISTS `find_child`$$
CREATE PROCEDURE  `find_child`( IN in_NodeID INT)
BEGIN
create temporary table KID_TABLE (nodeid INT);
insert ignore into KID_TABLE (nodeid) select nodeid 
from CORPORATENODE where parentid in (in_NodeID);
select * from KID_TABLE;
drop table KID_TABLE;
END $$
DELIMITER ;

当然,为什么要使用临时表呢?

DELIMITER $$
DROP PROCEDURE IF EXISTS `find_child`$$
CREATE PROCEDURE  `find_child`( IN in_NodeID INT)
BEGIN
select nodeid from CORPORATENODE where parentid in (in_NodeID);
END $$
DELIMITER ;

感谢Andreas等人,

我找到了一个解决这个问题的方法,就在发布后-典型的。但是直到现在我还不能发布我的解决方案。我使用Linux,但设置了lower_case_table_names=1,因此情况无关紧要。(我认为)

Andreas,我需要临时表,因为一旦我为一个节点选择了所有的子记录,我就需要更新表NODEVERSION中的所有子记录。我通过NODEVERSION表上的触发器运行这个,并且在更新调用表等时遇到了问题。这就是为什么我创建了一个新的CHILD_TABLE。

所以我发现(即使把DETERMINISTIC留在…对不起pilcrow !)下面的工作如预期-我所做的只是添加别名…(下面的代码与上面的代码略有不同,因为我为我的问题简化了上面的代码)

不完全理解为什么别名解决了最初的问题-但它有效。也许你们这些专家知道为什么?

    CREATE PROCEDURE `find_child`( IN NodeID int)
    DETERMINISTIC
    BEGIN
     declare nid INT;
     declare rows_before INT DEFAULT 0;
     declare rows_after INT DEFAULT 0;
     set nid= NodeID;
     delete from CHILD_TABLE;
     insert into CHILD_TABLE values (nid);
     set rows_before = (select count(*) from CHILD_TABLE);
     if rows_before !=rows_after then
       increment: repeat
        set rows_before = (select count(*) from CHILD_TABLE);
        insert ignore into CHILD_TABLE (nodeid) select b.nodeid from CORPORATENODE b 
        where b.parentid in (select c.nodeid from CHILD_TABLE c);
        set rows_after= (select count(*) from CHILD_TABLE);
        until rows_before =rows_after
       end repeat increment;
    end if;
    update NODEVERSION n set STATUS=1 where n.nodeid in 
    (select c.nodeid from CHILD_TABLE c);
   END

相关内容

  • 没有找到相关文章

最新更新