2011-11-21 36 views
3

我設計了返回所有子記錄給定節點一個簡單的MySQL的存儲過程。 我的問題是,當我手動輸入它會返回正確的結果 - 但是當我將相同的代碼放入存儲過程時,它只返回父ID。MySQL的存儲過程給予不同的結果,以命令行

我會很感激一些指導!

例如 - 當我把我的程序(代碼如下),我得到:

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 ; 

這裏的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

只是一個簡單的問題,你在Windows上運行嗎?你的情況看起來很糟糕,並且在缺省配置的mysql的linux系統上不起作用。 –

+0

你的程序不是確定性的。嘗試沒有(不正確)說明符。 – pilcrow

回答

2

MySQL將在變量節點Id回報您在您的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 ; 
+0

+1尼斯發現(並感謝下降DETERMINISTIC)。 – pilcrow

1

感謝安德烈亞斯等,

我發現了一個解決方法,以這種剛剛發佈之後 - 典型。 但是到現在爲止我的解決方案無法發佈。 我使用Linux,但有lower_case_table_names = 1設置,因此情況是不相關的。 (我想?)

安德烈亞斯,我需要臨時表,因爲一旦我選擇了回所有的子記錄的節點,然後我需要更新表NODEVERSION所有子記錄。我是通過NODEVERSION表上的觸發器來運行它,並在更新調用表等時遇到問題。這就是爲什麼我創建了一個新的CHILD_TABLE。

所以我發現,(即使在離開確定性在...對不起段落符號!) 以下預期一樣 - 我所做的只是添加別名... (下面的代碼是有點不同,從上面我簡單我的問題上面的代碼)

不完全理解爲什麼別名解決了最初的問題 - 但它的工作。也許你的專家知道爲什麼?

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 
相關問題