tags:

views:

56

answers:

2

I have the following code but it keeps presenting errors. The first part of the code creates the necessary table followed by - what should create stored procedures but it does not.

any ideas?

drop table if exists agent;

create table agent
(
agent_id int unsigned not null auto_increment primary key,
name varchar(32) not null,
commission_level tinyint unsigned default 0,
parent_agent_id int unsigned default null
)
engine = innodb;

insert into agent (name, commission_level, parent_agent_id) values

('I', 99, null),
  ('A', 7, 1),
  ('B', 6, 1),
    ('C', 5, 2),
    ('D', 6, 2),
    ('E', 5, 3),
    ('F', 2, 3),
      ('G', 5, 5),
      ('H', 1, 5);


delimiter ;

drop procedure if exists agent_hier;

delimiter #

create procedure agent_hier
(
in p_agent_id int unsigned
)
proc_main:begin

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


create temporary table hier(
 parent_agent_id int unsigned, 
 agent_id 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 agent a inner join hier on a.parent_agent_id = hier.agent_id and hier.depth = dpth) then

        insert into hier 
            select a.parent_agent_id, a.agent_id, dpth + 1 from agent a
            inner join tmp on a.parent_agent_id = tmp.agent_id 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.agent_id,
 a.name as agent_name,
 if(a.agent_id = b.agent_id, null, b.agent_id) as parent_agent_id,
 if(a.agent_id = b.agent_id, null, b.name) as parent_agent_name,
 hier.depth,
 a.commission_level
from 
 hier
inner join agent a on hier.agent_id = a.agent_id
inner join agent b on hier.parent_agent_id = b.agent_id
order by
 -- dont want to sort by depth but by commision instead - i think ??
 -- hier.depth, hier.agent_id; 
 a.commission_level desc;

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

end proc_main #


delimiter ;


/*

select * from agent;

call agent_hier(1);
call agent_hier(2);
call agent_hier(3);
call agent_hier(5);
*/
+1  A: 

I tried your SQL code, and works for me, I assume your user account doesn't have the correct privileges?

try

SHOW GRANTS;

and make sure that the user has the "Create routine" privileges

Kevin Bakker
+1  A: 

i've made a navicrap compatible script for you here http://pastie.org/1112694 - should run fine now providing you have the relevant privileges :P

Affected rows: 0 Time: 0.001ms

f00
haha - why the "navicrap" hate?
JM4
did you get it to run ?? toad is much better btw http://toadsoft.com/toadmysql/ (and it's free)
f00
@f00 - got the script to run after a few extra mods but the php is causing errors: Query failed with error: PROCEDURE db.agent_hier can't return a result set in the given context
JM4
I did download Toad yesterday from your suggestion but I like the UI of navi"crap" so much more and feel it is much simpler to use. Maybe i'll give it another shot.
JM4
i'll show you how to setup toad so it's sexy :P
f00
@f00 - any idea on the PHP error I'm getting?
JM4
yes it's a php mysql extension issue - older versions of this extension don't support calling sprocs, you need to use mysqli extension (i for improved although that's debatable) or upgrade your version of php so it has the latest mysql extension :)
f00
got ya - i've been debating moving over to mysqli for everything anyway. Of note, i'm running php 5.3.2
JM4
@f00 - the simple example I gave is actually realistic in nature with a 'live' table that has over 20 fields. I certainly don't mind paying for consulting services as you are the only person who has been able to give a decent (albeit great) answer to a painful problem we've had. There truly are only 4 fields among the twenty that are 'linked while all others simply populate information about that particular agent. The main reason for being able to pull information this way was to speed the process and be able to sort by column. Let me know if you are interested.
JM4
the biggest changes needed really are the following: 1) the system needs to pass the commission level into a query and return only the downline agents from that particular agent instead of from the entire system as this does now (changing call agent_hier(2) does nothing but blank). Also, I will allow 'sort' variables to occur so there can be no sorting within the actual procedure itself
JM4
oh i get results for 1,2,3,5 - the nodes that have children. i will be more than happy to spend more time on this with you but not sure how you can go about contacting me outside of SO or vice versa.
f00
you can find my contact details here http://f00bar.myopenid.com
f00