I am trying to write a mysql stored procedure with the following functions :
- Inputs are report parameters including report type, database to run against and some date and filter parameters
- The procedure looks up the report in table (report) and reads the report parameters.
- some reports are simple queries while others are UNIONS of 2 reports (
isunion=1
) - after reading the report parameters from the report table, the procedure passes these to the build_report function which puts it together and returns the sql query.
- in the case of single query, the procedure works perfectly (i.e only 1 report part) but where there are 2 parts, the procedure fails. It seems unable to get a value from the build_report function even though the part1 of a multi part query is the almost identical as the case for report with a single query (is_union=0) except for getting the report_id for the part from the reports table.
What am I missing ? any insight would be hugely appreciated.
The below procedure works perfectly when isunion=0
but fails when isunion=1
(even if I rem out part 2 altogether)
CREATE PROCEDURE `runreport_u`(
in all_active INT(1),
in reportid INT(10),
in db_id INT(10),
in start_date date,
in end_date date,
in inc_grpby INT(1),
OUT qry_part varchar(20000), #only outputing these to help debug
OUT qry_part1 varchar(20000),
OUT qry_part2 varchar(50000),
OUT qry varchar(40000),
OUT union_rep_id1 int(10),
OUT union_rep_id2 int(10),
OUT isunion int(10))
BEGIN
# purpose - this procedures looks up the specifications of a report query in table report. If the report is a single query the procedure works perfectly (case isunion=0) . When the qry is made up of 2 queries to be unionized, the build_report function which builds the parts seems to return nothing.
DECLARE part int DEFAULT NULL;
# is this report a union
SELECT is_union INTO isunion FROM report WHERE report_id=@reportid;
IF isunion=0 THEN
#report is not a union
SET part=1;
SET union_rep_id1=reportid;
SET qry_part = build_report(all_active,union_rep_id1,db_id,start_date,end_date,inc_grpby);
#log the components into gen table (more for debugging than anything else)
INSERT INTO gen (report_number,run_date,part_number,part_report_number,qry_part,part_order,param_all_active,param_report_id,param_db_id,param_start_date,param_end_date,param_incgrp) VALUES (reportid, now(),part,COALESCE(union_rep_id1,999),qry_part,part,all_active,reportid,db_id,start_date,end_date,inc_grpby);
SET qry=qry_part;
ELSE
#report has 2 or more parts
#*** first part
SET part=1;
#set the first report part - works (returns same union_rep_id as above)
SELECT union_report_id1 INTO union_rep_id1 FROM report WHERE report_id=reportid;
#get the query - in principle identical to the above but works above and returns nothing here
SET qry_part1 = build_report(all_active,union_rep_id1,db_id,start_date,end_date,inc_grpby);
INSERT INTO gen (report_number,run_date,part_number,part_report_number,qry_part,part_order,param_all_active,param_report_id,param_db_id,param_start_date,param_end_date,param_incgrp) VALUES (reportid, now(),part,COALESCE(union_rep_id1,999),qry_part1,part,all_active,reportid,db_id,start_date,end_date,inc_grpby);
#*** second part
SET part=2;
SELECT union_report_id2 INTO union_rep_id2 FROM report WHERE report_id=reportid;
SET qry_part2 = build_report(all_active,union_rep_id2,db_id,start_date,end_date,inc_grpby);
INSERT INTO gen (report_number,run_date,part_number,part_report_number,qry_part,part_order,param_all_active,param_report_id,param_db_id,param_start_date,param_end_date,param_incgrp) VALUES (reportid, now(),part,COALESCE(union_rep_id2,999),qry_part,part,all_active,reportid,db_id,start_date,end_date,inc_grpby);
#*******
#join the parts together in UNION
SET qry=CONCAT(qry_part,' UNION ',qry_part2);
END IF;
#had to add the line below otherwise Prepare stmt failed to recognize qry as variable
SET @final_qry=qry;
PREPARE stmt FROM @final_qry;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
#fails if isunion=1
END