MySQL, stored-function, using STRING variable as QUERY

Brook Julias picture Brook Julias · Aug 18, 2010 · Viewed 16.4k times · Source

I was wondering if it is possible in a mysql stored-function or stored-procedure compose a mysql query as a string variable you can execute later? I have a stored-function get_district_part ((district_id INT,county_id INT,city_id INT,zip_id INT)) RETURNS INT that references the table:

CREATE TABLE IF NOT EXISTS `modx`.covereage_district_part(
    id      INT     NOT NULL    AUTO_INCREMENT  PRIMARY KEY,
    districtID  INT     NOT NULL,
    countyID    INT,
    cityID      INT,
    zipID       INT,
    FOREIGN KEY (districtID) REFERENCES `modx`.coverage_district (id),
    FOREIGN KEY (countyID) REFERENCES `modx`.coverage_county (id),
    FOREIGN KEY (cityID) REFERENCES `modx`.coverage_city (id),
    FOREIGN KEY (zipID) REFERENCES `modx`.coverage_zip (id)
);

get_distrct_part is meant to return the id of rows mathing district_id and some combination of county_id, city_id, and zip_id. The thing is I want to return the id of the row matching the exact combination of ids not the ids of rows that contain any of those ideas. To do that, I am wanting to segment my query statement so it is built specific to the ids provided. I am trying to not have to match nulls if I can.

I realize this can be easily done with PHP, but I would like the do this as mysql stored process if I can for no other reason then all the other functions for this are stored processes.

Answer

Bill Karwin picture Bill Karwin · Aug 18, 2010

Yes, you can PREPARE and EXECUTE a string as dynamic SQL in a stored procedure.

delimiter //
CREATE PROCEDURE get_district_part (district_id INT, county_id INT, city_id INT, zip_id INT)
BEGIN
  SET @query = 'SELECT id FROM covereage_district_part WHERE 1=1';

  IF (district_id IS NOT NULL) THEN
    SET @query = CONCAT(@query, ' AND districtID=', district_id);
  END IF;

  IF (county_id IS NOT NULL) THEN
    SET @query = CONCAT(@query, ' AND countyID=', county_id);
  END IF;

  IF (city_id IS NOT NULL) THEN
    SET @query = CONCAT(@query, ' AND cityID=', city_id);
  END IF;

  IF (zip_id IS NOT NULL) THEN
    SET @query = CONCAT(@query, ' AND zipID=', zip_id);
  END IF;

  PREPARE stmt1 FROM @query;

  EXECUTE stmt1;
END //
delimiter ;

call get_district_part(1,1,1,1);
call get_district_part(1,1,null,null);

note: You cannot, however, execute dynamic SQL in a stored function. Your question mentions declaring your routine with a RETURNS clause which would be a stored function.