【问题标题】:How to Pass Variable into a MySQL Stored Procedure from PHP如何从 PHP 将变量传递到 MySQL 存储过程
【发布时间】:2010-09-03 15:37:17
【问题描述】:

我有以下存储过程:

proc_main:begin

declare done tinyint unsigned default 0;
declare dpth smallint unsigned default 0;


create temporary table hier(
 AGTREFERRER int unsigned, 
 AGTNO int unsigned, 
 depth smallint unsigned default 0
)engine = memory;

insert into hier values (p_agent_id, p_agent_id, dpth);

/* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */

create temporary table tmp engine=memory select * from hier;

while done <> 1 do

  if exists( select 1 from agents a inner join hier on a.AGTREFERRER = hier.AGTNO and hier.depth = dpth) then

    insert into hier 
      select a.AGTREFERRER, a.AGTNO, dpth + 1 from agents a
      inner join tmp on a.AGTREFERRER = tmp.AGTNO and tmp.depth = dpth;

    set dpth = dpth + 1;      

    truncate table tmp;
    insert into tmp select * from hier where depth = dpth;

  else
    set done = 1;
  end if;

end while;


select 
 a.AGTNO,
 a.AGTLNAME as agent_name,
 if(a.AGTNO = b.AGTNO, null, b.AGTNO) as AGTREFERRER,
 if(a.AGTNO = b.AGTNO, null, b.AGTLNAME) as parent_agent_name,
 hier.depth,
 a.AGTCOMMLVL
from 
 hier
inner join agents a on hier.AGTNO = a.AGTNO
inner join agents b on hier.AGTREFERRER = b.AGTNO
order by
 -- dont want to sort by depth but by commission instead - i think ??
 -- hier.depth, hier.agent_id; 
 a.AGTCOMMLVL desc;

drop temporary table if exists hier;
drop temporary table if exists tmp;

end proc_main

虽然该函数做得很好 - 它目前只允许通过 AGTCOMMLVL 降序排序。存储过程的目的是将 memberID 与其 parentID 和关联的 COMMLVL 匹配。一旦正确配对,我在第二个查询中使用 memberID 来返回有关该特定成员的信息。

我希望能够按任意数量的过滤器进行排序,但有以下问题:

  1. 我似乎找不到将变量传递到存储过程以更改其按字段排序的方法。

  2. 即使我可以 - 排序实际上可能只包含来自第二个查询的数据(例如名字、姓氏等)

  3. 即使语法正确,在第二个查询中运行排序也无济于事 - 它总是退回到存储过程的排序。

有什么想法吗?

编辑

我的 php 使用 mysqli 和代码:

$sql = sprintf("call agent_hier2(%d)", $agtid);
$resulta = $mysqli->query($sql, MYSQLI_STORE_RESULT) or exit(mysqli_error($mysqli));

【问题讨论】:

    标签: php mysql stored-procedures sorting


    【解决方案1】:

    如果要按存储过程的入参排序,需要使用Prepared staments 例如,

    DELIMITER //
    CREATE  PROCEDURE `test1`(IN field_name VARCHAR(40) )
    BEGIN
      SET @qr = CONCAT ("SELECT * FROM table_name ORDER BY ",  field_name);
    
      PREPARE stmt FROM @qr;
      EXECUTE stmt;
      DEALLOCATE PREPARE stmt;
    END //
    

    【讨论】:

      【解决方案2】:
      $stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
      $value = 'hello';
      $stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000); 
      
      // call the stored procedure
      $stmt->execute();
      
      print "procedure returned $value\n";
      

      【讨论】:

      • 我会试一试,但请注意,我的 php 是用 MySQLi 编写的
      • 也 - 我不确定是否可能,但第 3 部分对我来说是一个问题 - 从原始查询到存储过程的一些数据直到我的第二个查询(非存储过程)才存在也需要整理一下
      • 转换到mysqli应该没有那么难,但是,你真的应该学习和使用PDO。 1. PDO 在后端使用 mysqli,开销绝对最小, 2. 根据 Zend 的说法,PDO 是唯一支持的东西,所有其他 DB 功能将消失 在 PHP 7 中。 3. 几乎每个人都知道 PDO,而且将来只会越来越多。
      • 我试图返回并使用您在上面的 PHP 手册中的 PDO 语句,但它没有正确返回结果集。在我上面的 MySQLi 代码中,对我的存储过程的调用格式与 PDO 不同:
      • $sql = sprintf("call agent_hier2(%d)", $agtid) - 任何想法如何将其转换为 PDO?
      【解决方案3】:

      这也适用于 Mysql 5.6

      DELIMITER //
      CREATE PROCEDURE `test1`(IN field_name VARCHAR(40) )
      BEGIN
        "SELECT * FROM table_name ORDER BY ",  field_name);
      END //
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-05
        • 2014-07-27
        • 2014-10-17
        • 1970-01-01
        • 2011-09-15
        • 1970-01-01
        相关资源
        最近更新 更多