Archive for May 30th, 2007

The mysql prepare statement sucks heavy time. You can not (!?!!!) use it to template field and table names. So it is mostly useless for any heavy duty stored procedures that want to address different columns.

Here is a small function that will take care of that :)

SQL:
  1. DELIMITER //
  2. DROP FUNCTION  IF EXISTS substrCount//
  3. CREATE FUNCTION substrCount(x varchar(255), delim varchar(12)) returns int
  4. RETURN (length(x)-length(REPLACE(x, delim, '')))/length(delim);//
  5.  
  6. DROP FUNCTION  IF EXISTS charsplit//
  7. CREATE FUNCTION charsplit(x varchar(255), delim varchar(12), pos int) returns varchar(255)
  8. RETURN REPLACE(substring(substring_index(x, delim, pos), length(substring_index(x, delim, pos - 1)) + 1), delim, '');//
  9.  
  10. DROP FUNCTION  IF EXISTS replacefirst//
  11. CREATE FUNCTION replacefirst(haystack varchar(255), needle varchar(255),replacestr varchar(255)) returns varchar(255)
  12. BEGIN
  13.     IF LOCATE(needle,haystack)>0 THEN
  14.         SET @replaced=concat(LEFT(haystack,LOCATE(needle,haystack)-LENGTH(needle)),replacestr,RIGHT(haystack,LENGTH(haystack)-LOCATE(needle,haystack)));
  15.     ELSE
  16.         SET @replaced=haystack;
  17.     END IF;
  18.     RETURN @replaced;
  19. END;//
  20.  
  21. DROP FUNCTION  IF EXISTS properprepare//
  22. CREATE FUNCTION properprepare(template varchar(255), args varchar(255)) returns varchar(255)
  23. BEGIN
  24.  SET @i=0;
  25.  SET @numargs = substrCount(args,',');
  26.   WHILE @i <= @numargs DO
  27.       SET @i= @i+ 1;
  28.       SET template=replacefirst(template,'?',charsplit(args,',',@i));
  29.   END WHILE;
  30. RETURN template;
  31. END;//
  32.  
  33. DELIMITER ;

Test with

SQL:
  1. SELECT properprepare('SELECT ? FROM ? ', '*,user');
  2. SELECT properprepare('SELECT ? FROM ? ??', '*,user');
  3. SELECT properprepare('SELECT ? FROM ?', '*,user,test,test1');
  4. SELECT properprepare('SELECT ? FROM ? WHERE ?=?', '*,user,user_id,25');

-- So now you can in your stored procedures (at last!) do:

SQL:
  1. PREPARE update_query FROM properprepare('SELECT ? FROM ?', '*,mytable');
  2. EXECUTE update_query;
  3. PREPARE update_query FROM properprepare('SELECT ? FROM ?', 'myfield,mytable');
  4. EXECUTE update_query;

The first argument is the template with the question mark '?' as placeholder, the second is a comma separated string with the variables to replace. If you pass too few variables, the remaining placeholders will not be modified so they can be treated with the mysql PREPARE FROM, EXECUTE USING afterwards...

SQL:
  1. SET @a=25;
  2. SET @b=properprepare('SELECT ? FROM ? WHERE ?=?', '*,user,id_user');
  3. PREPARE stmnt FROM  @b;
  4. EXECUTE stmnt USING @a;

CAVEAT: Hardly tested, do not use in production without really testing this one

Click to continue reading

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.0 License.