Хранимая процедура MySQL, выдающая разные результаты в командной строке - PullRequest
3 голосов
/ 21 ноября 2011

У меня есть простая хранимая процедура 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 для таблицы PARENT

    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;

Ответы [ 2 ]

2 голосов
/ 21 ноября 2011

Mysql вернет вашу переменную 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 ;
1 голос
/ 30 ноября 2011

Спасибо Андреас и др.,

Я нашел обходной путь к этому сразу после публикации - типично.Но не могу опубликовать свое решение до сих пор.Я использую Linux, но у меня установлено lower_case_table_names = 1, поэтому случай не имеет значения.(Я думаю?)

Андреас, мне понадобилась временная таблица, так как после того, как я выбрал обратно все дочерние записи для узла, мне нужно было обновить все дочерние записи в таблице NODEVERSION.Я выполнял это через триггер в таблице NODEVERSION и столкнулся с проблемами при обновлении таблицы вызова и т. Д. Вот почему я создал новый CHILD_TABLE.

Так что я обнаружил это (даже оставив DETERMINISTIC вИзвините, Пилкроу!) Следующее сработало, как и ожидалось - все, что я сделал, это добавили псевдонимы ... (Код ниже немного отличается от приведенного выше, поскольку я упростил приведенный выше код для моего вопроса)понимаю, почему псевдонимы исправили первоначальную проблему - но это сработало.Возможно, вы, эксперты, знаете, почему?

    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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...