MySQL 在 select 语句中使用存储过程

Posted

技术标签:

【中文标题】MySQL 在 select 语句中使用存储过程【英文标题】:MySQL Using stored procedure in select statement 【发布时间】:2018-04-28 10:06:53 【问题描述】:

我有一个这样的存储过程:

$connection->query('
   drop procedure if exists listing_count;
   create procedure listing_count(IN parent int(11))
   begin
    declare count1 int(11) default 0;
    declare count2 int(11) default 1;
    create temporary table ids as (select id from category where id=parent);
    while count1<>count2 do
     set count1=(select count(id) from ids);
     insert into ids(id) select id from category where id not in(select id from ids) and related in(select id from ids);     
     set count2=(select count(id) from ids);
    end while;
    (select count(*) from listing_category where category in(select id from ids));
   end');

$fetch=$connection->query('select *,listing_count(id) as listing_count from category')->fetchall(pdo::FETCH_UNIQUE|pdo::FETCH_ASSOC);

我想像函数一样使用我的过程。这样listing_count 就会得到计数,以便我可以使用它。我需要创建一个单独的函数吗?程序可以获取我的计数并返回它吗?

把它变成这样的函数:

drop function if exists listing_count;
   create function listing_count(parent int(11)) returns int(11) deterministic
   begin
    declare count1 int(11) default 0;
    declare count2 int(11) default 1;
    create temporary table ids as (select id from category where id=parent);
    while count1<>count2 do
     set count1=(select count(id) from ids);
     insert into ids(id) select id from category where id not in(select id from ids) and related in(select id from ids);     
     set count2=(select count(id) from ids);
    end while;
    return (select count(*) from listing_category where category in(select id from ids));
   end

但这不起作用。我对过程与函数不是很熟悉,但我认为我不能像在过程中那样将所有功能添加到函数中。

【问题讨论】:

【参考方案1】:

我想像函数一样使用我的过程。

You Can't Do That™。

我建议您将您的 sp 转换为存储函数。在任何情况下这都是一个好主意,因为它返回一个值。按照您现在的方式,它返回一个单列单行结果集。如果它是一个函数,它将在您需要的每个上下文中轻松工作。相比之下,返回结果集的存储过程几乎没有那么容易使用。例如,看到这个。 How to use Table output from stored mysql Procedure

或者您可以编写一个存储函数来包装您的存储过程并返回值。在我看来,这是一个较差的解决方案,只是因为它具有额外的复杂性。

【讨论】:

我尝试将其更改为存储函数,但它停止工作 在某些情况下需要将过程包装在函数中,例如需要递归时 (MySQL stored functions are not allowed to recurse) DETERMINISTIC 表示函数的结果基于它的参数而不是其他任何东西,并且总是为相同的参数返回相同的值。 (优化器可以利用确定性函数的知识。)您的函数基于参数和表的内容,因此它不是确定性的。而且,“它停止工作”并不是很有用的信息。

以上是关于MySQL 在 select 语句中使用存储过程的主要内容,如果未能解决你的问题,请参考以下文章

MySQL使用游标

MYSQL存储过程select语句select不正确的ID

如何在 Redshift 中的 select 语句中使用存储过程

mysql 存储过程中的select into outfile语句生成的文件放哪里

存储过程中的 MySQL select 语句返回的结果与 proc 外部不同

mysql 存储过程中 查询语句后面的from加上变量名 怎么写