7

¿Es posible establecer el resultado de una declaración preparada en una variable? Estoy intentando crear el siguiente procedimiento almacenado pero está fallando:¿Cómo obtener el resultado escalar de una declaración preparada?

ERROR 1064 (42000) en la línea 31: Tiene un error en la sintaxis SQL; revise el manual que corresponde a su versión del servidor MySQL para la sintaxis correcta para usar cerca de '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 ; 

Respuesta

6

Puede parecer extraño, pero se pueden asignar la variable directamente en la cadena de declaración preparada: caso

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

-- ... 

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

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

prueba:

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 ; 

Resultado:

CALL myProc(400); 

+---------+ 
| result | 
+---------+ 
|  4 | 
+---------+ 
1 row in set (0.00 sec) 
+0

Ah! ¡¡Por supuesto!! –

+0

Sé que esta respuesta es muy antigua, pero ¿alguien me puede decir: cuando uso este código y uso CALL myProc (600), no devuelve un resultado de consulta vacío sino que devuelve lo que fue la última llamada "válida". ¿Por qué es eso y cómo puedo cambiar eso? Debería devolver 'result' como vacío cuando le paso un valor que no está en la tabla. – Meelah

1
No

siquiera seguro de por qué está utilizando SQL dinámico en su ejemplo - esto parece mucho más simple

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'); 
2

Usar este código

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

EXECUTE stmt; 

if(@i='a') then 
............ 
end if; 
Cuestiones relacionadas