views:

124

answers:

2

I have the following stored procedure:

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

While the function does its job well - it only currently allows sorting via AGTCOMMLVL descending order. The stored procedure's purpose is to match a memberID with their parentID and associated COMMLVL. Once paired appropriately,I use the memberID in a second query to return information about that particular member.

I would like to be able to sort by any number of filters but have the following problems:

  1. I can't seem to find a way to pass a variable into the stored procedure altering its sorting by field.

  2. Even if I could - the sort may actually only contain data from the second query (such as first name, last name, etc)

  3. Running a sort in the second query does nothing even though syntax is correct - it always falls back to the stored procedure's sort.

any ideas?

EDIT

My php uses mysqli with code:

$sql = sprintf("call agent_hier2(%d)", $agtid);
$resulta = $mysqli->query($sql, MYSQLI_STORE_RESULT) or exit(mysqli_error($mysqli));
A: 
$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";
hopeseekr
@hopeseekr - I'll give it a shot but note, my php is written in MySQLi
JM4
also - I'm not sure if possible but part 3 is a concern to me - some data from the original query into the stored procedure does not exist until the second query (non stored procedure) which i'll need to sort off of too
JM4
Converting to mysqli shouldn't be that difficult, however, you really should learn and use PDO. 1. PDO uses mysqli in the backend, and overhead is absolutely minimal,2. According to Zend, PDO is the only supported thing and *all* of the other DB functions will be *gone* in PHP 7.3. Almost everyone knows PDO and it will only get more so in the future.
hopeseekr
@hopeseekr - I attempted to go back and use the PDO statement you have above from the PHP manual but it does not return the result set properly. In my MySQLi code above, the call into my stored procedure is formatted differently than PDO :
JM4
$sql = sprintf("call agent_hier2(%d)", $agtid) - any ideas how to convert that into PDO?
JM4
+1  A: 

If you want to sort by input parameter of the stored procedure, you need to use Prepared staments For example,

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 //
a1ex07