{"id":339,"date":"2002-04-10T01:58:41","date_gmt":"2002-04-10T06:58:41","guid":{"rendered":"http:\/\/www.ashleyit.com\/blogs\/brentashley\/?p=339"},"modified":"2002-04-10T01:58:41","modified_gmt":"2002-04-10T06:58:41","slug":"simple-stored-procedure-emulation-with-phpmysql","status":"publish","type":"post","link":"https:\/\/ashleyit.com\/blogs\/brentashley\/2002\/04\/10\/simple-stored-procedure-emulation-with-phpmysql\/","title":{"rendered":"Simple Stored Procedure Emulation with PHP\/mySQL"},"content":{"rendered":"<p>My &#8220;third time, automate&#8221; rule came in handy again recently.  I&#8217;m doing all sorts of PHP\/mySQL work and I found myself hacking together the same SQL queries over and over with just some different filter or sort order.  Being used to stored procedures, I was missing the easier syntax.  <\/p>\n<p>Here&#8217;s what I came up with&#8230;.<br \/>\n<!--more--><br \/>\nrather than:<\/p>\n<pre>\nsql = \"select height, name from students where height>$minHeight order by $orderCol\";\n<\/pre>\n<p>I wanted to say something more along the lines of:<\/p>\n<pre>\ngetStudentsByHeight( minHeight, order );\n<\/pre>\n<p>Of course, I could wrap every such query in a PHP function, but I wanted to make it feel more like a stored procedure.<\/p>\n<p>So, I created a procs table in my database:<\/p>\n<pre>\nCREATE TABLE procs (\n  name varchar(50),\n  description text,\n  sqltext text,\n)\n<\/pre>\n<p>Then I created a record:<\/p>\n<pre>\nname: \n  getStudentsByHeight\ndescription: \n  getStudentsByHeight( minHeight [in cm] , order [by 1=height or 2=name])\nsqltext: \n  select height, name from students where height>$1 order by $2\n<\/pre>\n<p>And then I created a function I called sproc().  This function takes the name of a procedure, and its parameters in an array, so you can call it like this:<\/p>\n<pre>\nsql = sproc( 'getStudentsByHeight', array( 150, 2 ) );\n<\/pre>\n<p>sproc() iterates through the parameters and does a string replacement on the sql text for each.  Then it returns the sql.<\/p>\n<pre>\nfunction sproc($proc,$parms){\n  $sql=\"select sqltext from procs where name='$proc'\";\n  $rs=mysql_query($sql);\n  if (mysql_num_rows($rs)>0){\n    $row = mysql_fetch_row($rs);\n    $sqlText = $row[0];\n    if(isset($parms)){\n      if(is_array($parms)){\n        for($i=0;$i&lt;count($parms);$i++){\n          $sqlText=str_replace('$'.($i+1),$parms[$i],$sqlText);\n        }\n      }else{\n        $sqlText=str_replace('$1',$parms,$sqlText);\n      }    \n    }\n    return $sqlText;\n  }else{\n    print \"&lt;div>procedure [$proc] does not exist&lt;\/div>\";\n    exit();\n  }\n}\n<\/pre>\n<p>Now when I want to change the sql to include more fields and therefore more ordering choices, I only have to change it in the database, without ever touching the code!<\/p>\n<pre>\nselect height, name, shoesize from students where height>$1 order by $2\n<\/pre>\n<p>Of course, since you&#8217;d have to redo your display for the extra field, it&#8217;s not complete without a generic table building function.  That brings the entire table generation code to this line:<\/p>\n<pre>\nprint tblFromRS(mysql_query(sproc('getStudentsByHeight',array(150,2))));\n<\/pre>\n<pre>\nfunction tblFromRS($rs){\n  $s=\"&lt;table border=\"1\">&lt;tr>\";\n  while($fld = mysql_fetch_field($rs))$s.=\"&lt;th>$fld->name&lt;\/th>\";\n  $s.=\"&lt;\/tr>\\n\";\n  while($row = mysql_fetch_row($rs)){\n    $s.=\"&lt;tr>\";\n    for($i=0;$i&lt;mysql_num_fields($rs);$i++)$s.=\"&lt;td>$row[$i]&nbsp;&lt;\/td>\";\n    $s.=\"&lt;\/tr>\\n\";  \n  }\n  $s.=\"&lt;\/table>\\n\";\n  return $s;\n}\n<\/pre>\n<p>Now I can manage my sql queries all in the database.  On any new project, I just bring across the generic functions and the procs table and off I go.<\/p>\n<p>It&#8217;s no replacement for real stored procedures, but it&#8217;s a good stopgap.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My &#8220;third time, automate&#8221; rule came in handy again recently. I&#8217;m doing all sorts of PHP\/mySQL work and I found myself hacking together the same SQL queries over and over with just some different filter or sort order. Being used to stored procedures, I was missing the easier syntax. Here&#8217;s what I came up with&#8230;.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-339","post","type-post","status-publish","format-standard","hentry","category-blather"],"_links":{"self":[{"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/posts\/339","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/comments?post=339"}],"version-history":[{"count":0,"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/posts\/339\/revisions"}],"wp:attachment":[{"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/media?parent=339"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/categories?post=339"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ashleyit.com\/blogs\/brentashley\/wp-json\/wp\/v2\/tags?post=339"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}