Как получить скалярный результат из подготовленного утверждения? - PullRequest
8 голосов
/ 22 октября 2010

Можно ли установить результат из подготовленного оператора в переменную?Я пытаюсь создать следующую хранимую процедуру, но она не выполняется:

ОШИБКА 1064 (42000) в строке 31: в синтаксисе SQL возникла ошибка;проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса, который нужно использовать рядом с 'stmt USING @m, @c, @a;

DROP PROCEDURE IF EXISTS deleteAction;

DELIMITER $$
CREATE PROCEDURE deleteAction(
    IN modul CHAR(64),
    IN controller CHAR(64),
    IN actn CHAR(64))

MODIFIES SQL DATA

BEGIN

    PREPARE stmt FROM 'SELECT id 
                         FROM actions 
                        WHERE `module` = ? 
                          AND `controller` = ? 
                          AND `action` = ?';

    SET @m = modul;
    SET @c = controller;
    SET @a = actn;

    SET @i = EXECUTE stmt USING @m, @c, @a;

    DEALLOCATE PREPARE stmt;

    DELETE FROM acl WHERE action_id = @i;
    DELETE FROM actions WHERE id = @i; 

END 
$$
DELIMITER ;

Ответы [ 3 ]

6 голосов
/ 22 октября 2010

Может показаться странным, но вы можете назначить переменную непосредственно в подготовленной строке оператора:

PREPARE stmt FROM 'SELECT @i := id FROM ...';

-- ...

EXECUTE stmt USING @m, @c, @a;

-- @i will hold the id returned from your query.

Контрольный пример:

CREATE TABLE actions (id int, a int);

INSERT INTO actions VALUES (1, 100);
INSERT INTO actions VALUES (2, 200);
INSERT INTO actions VALUES (3, 300);
INSERT INTO actions VALUES (4, 400);
INSERT INTO actions VALUES (5, 500);

DELIMITER $$
CREATE PROCEDURE myProc(
    IN p int
)

MODIFIES SQL DATA

BEGIN

    PREPARE stmt FROM 'SELECT @i := id FROM actions WHERE `a` = ?';

    SET @a = p;

    EXECUTE stmt USING @a;

    SELECT @i AS result;

    DEALLOCATE PREPARE stmt;

END 
$$
DELIMITER ;

Результат:

CALL myProc(400);

+---------+
| result  |
+---------+
|       4 |
+---------+
1 row in set (0.00 sec)
2 голосов
/ 22 марта 2013

Используйте этот код

PREPARE stmt FROM 'SELECT ''a'' into @i' ;

EXECUTE stmt;

if(@i='a') then
............
end if;
1 голос
/ 23 октября 2010

даже не уверен, почему вы используете динамический sql в вашем примере - это кажется намного проще

drop procedure if exists deleteAction;

delimiter #

create procedure deleteAction
(
 in p_modul char(64),
 in p_controller char(64),
 in p_actn char(64)
)
begin

declare v_id int unsigned default 0;

    select id into v_id from actions where 
          module = p_modul and controller = p_controller and action = p_actn;

    delete from acl where action_id = v_id;
    delete from actions where id = v_id; 

    select v_id as result;

end #

delimiter ;

call deleteAction('mod','ctrl','actn');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...