如何从准备好的语句中获取标量结果?

发布于 2024-09-28 20:15:10 字数 844 浏览 0 评论 0原文

是否可以将准备好的语句的结果设置为变量?我正在尝试创建以下存储过程,但失败了:

第 31 行出现错误 1064 (42000):您的 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 ;

Is it possible to set the result from a prepared statement into a variable? I am trying to create the following stored procedure but it is failing:

ERROR 1064 (42000) at line 31: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '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 ;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月亮坠入山谷 2024-10-05 20:15:10

这可能看起来很奇怪,但您可以直接在准备好的语句字符串中分配变量:

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)

It may seem strange, but you can assign the variable directly in the prepared statement string:

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

-- ...

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

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

Test case:

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 ;

Result:

CALL myProc(400);

+---------+
| result  |
+---------+
|       4 |
+---------+
1 row in set (0.00 sec)
我不吻晚风 2024-10-05 20:15:10

使用此代码

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

EXECUTE stmt;

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

Use this code

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

EXECUTE stmt;

if(@i='a') then
............
end if;
幸福还没到 2024-10-05 20:15:10

甚至不确定为什么在示例中使用动态 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');

not even sure why you're using dynamic sql in your example - this seems a lot simpler

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');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文