7

Kann das Ergebnis einer vorbereiteten Anweisung in eine Variable gesetzt werden? Ich versuche, die folgende gespeicherte Prozedur zu erstellen, aber es schlägt fehl:Wie skalare Ergebnisse aus vorbereiteten Anweisungen erhalten?

Fehler 1064 (42000) Zeile 31: Sie haben einen Fehler in Ihrer SQL-Syntax; Überprüfen Sie das Handbuch, das Ihrer MySQL-Server-Version entspricht, für die richtige Syntax in der Nähe von '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 ; 

Antwort

6

Es mag seltsam erscheinen, aber Sie können die Variable direkt in der vorbereiteten Anweisung String zuweisen:

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

-- ... 

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

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

Testfall:

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 ; 

Ergebnis:

CALL myProc(400); 

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

Ah! Na sicher!! –

+0

Ich weiß, dass diese Antwort sehr alt ist, aber kann mir jemand sagen: Wenn ich diesen Code benutze und ich CALL myProc (600) verwende, gibt es kein leeres Abfrageergebnis zurück, sondern gibt den letzten 'gültigen' Aufruf zurück. Warum ist das und wie kann ich das ändern? Es sollte "result" als leer zurückgeben, wenn ich einen Wert übergebe, der nicht in der Tabelle enthalten ist. – Meelah

1

nicht einmal sicher, warum Sie dynamische SQL in Ihrem Beispiel verwenden - dies scheint viel einfacher

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

Verwenden Sie diesen Code

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

EXECUTE stmt; 

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