我有一个简单的MySQL存储过程,用于返回给定节点的所有子记录。 我的问题是,当我手动输入它时会返回正确的结果 - 但是当我将相同的代码放入存储过程时,它只返回父ID。
我真的很感激一些指导!
例如 - 当我调用我的程序(代码在下面)时,我得到:
call find_child(1006);
+--------+
| nodeid |
+--------+
| 1006 |
| 1006 |
| 1006 |
| 1006 |
+--------+
4 rows in set (0.01 sec)
但是 - 当我剪切并粘贴命令时,我得到了正确的结果集:
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 ;
这是PARENT表的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;
答案 0 :(得分:2)
Mysql将在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 ;
答案 1 :(得分:1)
感谢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