<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>MacLochlainns Weblog &#187; LAMP</title>
	<atom:link href="http://blog.mclaughlinsoftware.com/category/lamp/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.mclaughlinsoftware.com</link>
	<description>Michael McLaughlin's Technical Blog</description>
	<lastBuildDate>Wed, 28 Jul 2010 00:02:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>PHP Function Primer</title>
		<link>http://blog.mclaughlinsoftware.com/2010/04/02/php-function-primer/</link>
		<comments>http://blog.mclaughlinsoftware.com/2010/04/02/php-function-primer/#comments</comments>
		<pubDate>Sat, 03 Apr 2010 04:17:14 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3689</guid>
		<description><![CDATA[Added a new PHP Function Primer for my students. This one&#8217;s not large but fits as a page better. If you&#8217;re interested it&#8217;s here. It covers: Function Definitions Creating &#38; Using Functions Pass-by-value Functions Pass-by-reference Functions Dynamic Functions Function Default Parameters Variable-length Parameter Lists]]></description>
			<content:encoded><![CDATA[<p>Added a new PHP Function Primer for my students. This one&#8217;s not large but fits as a page better. If you&#8217;re interested it&#8217;s <a href="http://blog.mclaughlinsoftware.com/php-programming/php-function-tutorial/">here</a>.</p>
<p>It covers:</p>
<ul>
<li>Function Definitions</li>
<li>Creating &amp; Using Functions</li>
</ul>
<ul style="padding-left:30px">
<li>Pass-by-value Functions</li>
<li>Pass-by-reference Functions</li>
<li>Dynamic Functions</li>
</ul>
<ul>
<li>Function Default Parameters</li>
<li>Variable-length Parameter Lists</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2010/04/02/php-function-primer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Tutorial Available</title>
		<link>http://blog.mclaughlinsoftware.com/2010/03/29/php-tutorial-available/</link>
		<comments>http://blog.mclaughlinsoftware.com/2010/03/29/php-tutorial-available/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 17:11:43 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[OPAL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3683</guid>
		<description><![CDATA[I finally got around to writing that PHP Tutorial. It&#8217;s a bit large and takes about 10 seconds to load or longer depending on your connection and machine. It covers the basics from writing your first page to loops. It was too large for a blog post, so it&#8217;s a blog page. Click on the [...]]]></description>
			<content:encoded><![CDATA[<p>I finally got around to writing that PHP Tutorial. It&#8217;s a bit large and takes about 10 seconds to load or longer depending on your connection and machine. It covers the basics from writing your first page to loops. It was too large for a blog post, so it&#8217;s a blog page. Click on the <a href="http://blog.mclaughlinsoftware.com/php-programming/basic-php-tutorial/">link if you&#8217;d like to check it out</a>.</p>
<p>I plan others on functions, objects, and files. Then, I&#8217;ll get to tutorials against databases.</p>
<p>Naturally, suggestions are always welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2010/03/29/php-tutorial-available/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Standard Group By</title>
		<link>http://blog.mclaughlinsoftware.com/2010/03/10/mysql-standard-group-by/</link>
		<comments>http://blog.mclaughlinsoftware.com/2010/03/10/mysql-standard-group-by/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 06:54:12 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3595</guid>
		<description><![CDATA[Teaching SQL is interesting because folks try syntax that experience would tell you shouldn&#8217;t work. It was interesting when I discovered what should be broken from my perspective but was expected behavior in MySQL. It became clearer to me why it&#8217;s there as I did some experimenting with it enabled and disabled. While I&#8217;d still [...]]]></description>
			<content:encoded><![CDATA[<p>Teaching SQL is interesting because folks try syntax that experience would tell you shouldn&#8217;t work. It was interesting when I discovered what should be broken from my perspective but was expected behavior in MySQL. It became clearer to me why it&#8217;s there as I did some experimenting with it enabled and disabled. While I&#8217;d still argue it&#8217;s broken, it&#8217;s the only way to get support for advanced aggregation concepts.</p>
<p>The reason that I find that it broken is a matter of perspective not standards. The fact that you can select a set of non-aggregated columns with an aggregated column, and exclude one, more than one, or all of the non-aggregated columns from the <code>GROUP BY</code> clause seemed like a broken behavior. The MySQL behavior is explained in <a href="http://dev.mysql.com/doc/refman/5.1/en/group-by-hidden-columns.html">Chapter 11.12.3 of the MySQL 5.1 Reference</a>. What wasn&#8217;t clear from the documentation when I read it was why the behavior is allowed. Gary&#8217;s comment on the original post made me look more deeply into the behavior.</p>
<p>If you check the referenced documentation, the process is called <code>GROUP BY</code> hidden columns. That label didn&#8217;t immediately resonate with me. That&#8217;s probably of my background with IBM&#8217;s DB2 and Oracle. I&#8217;m so accustom to how they work, that sometimes I think they set the standards but they don&#8217;t. It turns out that the <code>GROUP BY</code> clause in the ANSI SQL standards doesn&#8217;t allow for expressions.</p>
<p>The default configuration of MySQL allows for the expressions (functions) in the <code>GROUP BY</code> clause. The documentation refers to <em>hidden columns</em>, which are in point of fact expressions in the <code>GROUP BY</code> clause. MySQL does support expressions in the <code>GROUP BY</code> by default, and requires, like Oracle, that when you use an expression in the <code>SELECT</code> clause that you mirror it in the <code>GROUP BY</code> clause. This means you group on the result of the expression, not a column in the table or view.</p>
<p>In the default configuration, you have three options. They are determinate results, indeterminate results, and hidden column results. The following cover these components. </p>
<p><span style="font-size:115%"><strong>Determinate Results</strong></span></p>
<p>Determinate results are straight forward. They require that all non-aggregated columns in the <code>SELECT</code> clause are mirrored in the <code>GROUP BY</code> clause. This means that the non-aggregated column values are the key upon which results are aggregated.</p>
<p>An example of determinate results is:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>   key_one
<span style="color: #66cc66;">,</span>        key_two
<span style="color: #66cc66;">,</span>        SUM<span style="color: #66cc66;">&#40;</span>counter<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">FROM</span>     grouping
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> key_one
<span style="color: #66cc66;">,</span>        key_two;</pre></td></tr></table></div>

<p><span style="font-size:115%"><strong>Indeterminate Results</strong></span></p>
<p>Indeterminate results isn&#8217;t straight forward but isn&#8217;t hard to grasp. An indeterminate result set is returned when one or more non-aggregated columns in a <code>SELECT</code> clause aren&#8217;t listed in the <code>GROUP BY</code> clause. The columns listed in the <code>SELECT</code> clause but excluded from the <code>GROUP BY</code> clause return meaningless values because they&#8217;re column values chosen indeterminately from all pre-aggregated rows.  </p>
<p>The following query runs in a generically configured MySQL instance without an error. It returns a meaningless <code>key_two</code> column value from the pre-aggregated row set. In the example, the aggregation column counts the unique <code>key_one</code> column values. This behavior makes <code>key_one</code> a determinate value, and <code>key_two</code> an indeterminate</code> value.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>   key_one
<span style="color: #66cc66;">,</span>        key_two
<span style="color: #66cc66;">,</span>        SUM<span style="color: #66cc66;">&#40;</span>counter<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">FROM</span>     grouping
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> key_one;</pre></td></tr></table></div>

<p>You can fix this mixed return set by adding the <code>key_two</code> column to the <code>GROUP BY</code> clause, which would return a determinate set. Alternatively, you can prevent the default behavior for the <code>GROUP BY</code> clause <a href="http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html">by adding the <code>ONLY_FULL_GROUP_BY</code> mode variable</a> to your <code>SQL_MODE</code> system variable.</p>
<p>After setting the <code>SQL_MODE></code> variable, a <code>GROUP BY</code> must contain all non-aggregated columns. When you make this change to the <code>SQL_MODE</code> system variable, you also disable any queries that use an expression in their <code>GROUP BY</code> clause. Those queries with expressions in the group by will now raise an <code>ERROR 1055</code> exception, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">ERROR <span style="color: #cc66cc;">1055</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">42000</span><span style="color: #66cc66;">&#41;</span>: <span style="color: #ff0000;">'sampledb.grouping.key_two'</span> isn<span style="color: #ff0000;">'t in GROUP BY</span></pre></div></div>

<p>If you want to prevent indeterminate results and don't use expressions in the <code>GROUP BY</code> clause, you can add the <code>ONLY_FULL_GROUP_BY</code> mode to your <code>SQL_MODE</code> system variable. You can do that during a session with the following syntax:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SET</span> SQL_MODE<span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> CONCAT<span style="color: #66cc66;">&#40;</span>@@sql_mode<span style="color: #66cc66;">,</span><span style="color: #ff0000;">',ONLY_FULL_GROUP_BY'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;</pre></div></div>

<p>Or, you can start the <code>mysqld</code> with the following option:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">mysqld --sql_mode=<span style="color: #ff0000;">&quot;sql_mode1,sql_mode2, ... ,sql_mode(n+1)&quot;</span></pre></div></div>

<p>A better alternative, is to add it to the <code>my.cnf</code> configuration file on Linux, or <code>my.ini</code> configuration file on Windows. You can add it to this line, which is done at the end of the line.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># Set the SQL mode to strict</span>
sql-mode=<span style="color: #ff0000;">&quot;STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY&quot;</span></pre></div></div>

<p>If you opt for changing it at the server configuration file, you must stop and restart the <code>mysqld</code> process. You can do that on Windows from the command line, like this on Windows provide the service name is <code>mysql</code>. If you've set the Windows service to <code>mysql51</code>, then you need to substitute <code>mysql51</code> for <code>mysql</code>.</p>
<p><span style="font-size:115%"><strong>Hidden Column Results</strong></span></p>
<p>A hidden column result, is a result generated by an expression in the <code>GROUP BY</code> clause. The following is a query that lets you sum transactions by the month name. This is supported by the default behavior of <em>hidden columns</em>. The following is an approach that you might find in Oracle because they don't support aggregation by only part of the non-aggregated columns in a query.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>   il<span style="color: #66cc66;">.</span>month <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;MON-YEAR&quot;</span>
<span style="color: #66cc66;">,</span>        il<span style="color: #66cc66;">.</span>base <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;BASE&quot;</span>
<span style="color: #66cc66;">,</span>        il<span style="color: #66cc66;">.</span>plus10 <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;10_PLUS&quot;</span>
<span style="color: #66cc66;">,</span>        il<span style="color: #66cc66;">.</span>plus20 <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;20_PLUS&quot;</span>
<span style="color: #993333; font-weight: bold;">FROM</span>    <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span>   CONCAT<span style="color: #66cc66;">&#40;</span>UPPER<span style="color: #66cc66;">&#40;</span>SUBSTRING<span style="color: #66cc66;">&#40;</span>MONTHNAME<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'-'</span><span style="color: #66cc66;">,</span>EXTRACT<span style="color: #66cc66;">&#40;</span>YEAR <span style="color: #993333; font-weight: bold;">FROM</span> t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> month
         <span style="color: #66cc66;">,</span>        MONTH<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> sortkey
         <span style="color: #66cc66;">,</span>        LPAD<span style="color: #66cc66;">&#40;</span>CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'$'</span><span style="color: #66cc66;">,</span>FORMAT<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_amount<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">' '</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> base
         <span style="color: #66cc66;">,</span>        LPAD<span style="color: #66cc66;">&#40;</span>CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'$'</span><span style="color: #66cc66;">,</span>FORMAT<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_amount<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">1.1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">' '</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> plus10
         <span style="color: #66cc66;">,</span>        LPAD<span style="color: #66cc66;">&#40;</span>CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'$'</span><span style="color: #66cc66;">,</span>FORMAT<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_amount<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">1.2</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">' '</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> plus20
         <span style="color: #993333; font-weight: bold;">FROM</span>     transaction t
         <span style="color: #993333; font-weight: bold;">WHERE</span>    EXTRACT<span style="color: #66cc66;">&#40;</span>YEAR <span style="color: #993333; font-weight: bold;">FROM</span> t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2009</span>
         <span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> CONCAT<span style="color: #66cc66;">&#40;</span>UPPER<span style="color: #66cc66;">&#40;</span>SUBSTRING<span style="color: #66cc66;">&#40;</span>MONTHNAME<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'-'</span><span style="color: #66cc66;">,</span>EXTRACT<span style="color: #66cc66;">&#40;</span>YEAR <span style="color: #993333; font-weight: bold;">FROM</span> t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">,</span>        MONTH<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> il
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> il<span style="color: #66cc66;">.</span>sortkey;</pre></td></tr></table></div>

<p style="clear:both">
<p>The interesting thing about MySQL's approach is that the Oracle equivalent of an inline view is unnecessary. You can simply switch the functions like the exmaple below.</p>
<p style="clear:both">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>   DATE_FORMAT<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'%m-%Y'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> month
<span style="color: #66cc66;">,</span>        MONTH<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> sortkey
<span style="color: #66cc66;">,</span>        LPAD<span style="color: #66cc66;">&#40;</span>CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'$'</span><span style="color: #66cc66;">,</span>FORMAT<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_amount<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">' '</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> base
<span style="color: #66cc66;">,</span>        LPAD<span style="color: #66cc66;">&#40;</span>CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'$'</span><span style="color: #66cc66;">,</span>FORMAT<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_amount<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">1.1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">' '</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> plus10
<span style="color: #66cc66;">,</span>        LPAD<span style="color: #66cc66;">&#40;</span>CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'$'</span><span style="color: #66cc66;">,</span>FORMAT<span style="color: #66cc66;">&#40;</span>SUM<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_amount<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">1.2</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">' '</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> plus20
<span style="color: #993333; font-weight: bold;">FROM</span>     transaction t
<span style="color: #993333; font-weight: bold;">WHERE</span>    EXTRACT<span style="color: #66cc66;">&#40;</span>YEAR <span style="color: #993333; font-weight: bold;">FROM</span> t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2009</span>
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> DATE_FORMAT<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">,</span><span style="color: #ff0000;">'%m-%Y'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span>        MONTH<span style="color: #66cc66;">&#40;</span>t<span style="color: #66cc66;">.</span>transaction_date<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> sortkey;</pre></td></tr></table></div>

<p>When you add the <code>ONLY_FULL_GROUP_BY</code> mode to your <code>SQL_MODE</code> system variable, you disallow this type of behavior and the query would no longer work. It would return the following error:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">ERROR <span style="color: #cc66cc;">1055</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">42000</span><span style="color: #66cc66;">&#41;</span>: <span style="color: #ff0000;">'sampledb.t.transaction_date'</span> isn<span style="color: #ff0000;">'t in GROUP BY</span></pre></div></div>

<div class="dropdownbox" style="padding-left:20px;background:#FFFFFF">
<p title="Click to see content ..." class="dropdownclick"><strong><em><span style="font-size:125%">Complete Code Sample</span></em></strong> <span>&darr;</span></p>
<p style="clear: both">
Expand this section to see the sample working code for indeterminate results.</p>
<div>
<p>This builds the <code>GROUPING</code> table, inserts nine rows, and tests it before and after setting the variable in the session. The change reverts after you exit and re-enter the database.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- Conditionally drop sample table.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'DROP TABLE IF EXISTS grouping'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> grouping;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Create sample table.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'CREATE TABLE grouping'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> grouping
<span style="color: #66cc66;">&#40;</span> key_one   CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> key_two   CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> counter   INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Insert nine rows into the sample table.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'INSERT INTO grouping'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> grouping <span style="color: #993333; font-weight: bold;">VALUES</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'One'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Uno-1'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Two'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Due-1'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Three'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Tre-1'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'One'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Uno-2'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Two'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Due-2'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Three'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Tre-2'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'One'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Uno-3'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Two'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Due-3'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Three'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Tre-3'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Query with hidden columns, no enforcement on non-aggregate columns.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'SELECT non-aggregates FROM grouping with hidden columns'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">SELECT</span> key_one<span style="color: #66cc66;">,</span> key_two<span style="color: #66cc66;">,</span> SUM<span style="color: #66cc66;">&#40;</span>counter<span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">FROM</span>   grouping
<span style="color: #993333; font-weight: bold;">GROUP</span> <span style="color: #993333; font-weight: bold;">BY</span> key_one;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Check current system mode variable assignment.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'SELECT @@sql_mode'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">SELECT</span> @@sql_mode;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Append the mode to the existing system mode variable.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'SET SQL_MODE=(SELECT ...)'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">SET</span> SQL_MODE<span style="color: #66cc66;">=</span><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> CONCAT<span style="color: #66cc66;">&#40;</span>@@sql_mode<span style="color: #66cc66;">,</span><span style="color: #ff0000;">',ONLY_FULL_GROUP_BY'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Check modified system mode variable assignment.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'SELECT @@sql_mode'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">SELECT</span> @@sql_mode;</pre></div></div>

</div>
</div>
<p style="clear:both">
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2010/03/10/mysql-standard-group-by/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Debugging MySQL Procedures</title>
		<link>http://blog.mclaughlinsoftware.com/2010/02/27/debugging-mysql-procedures/</link>
		<comments>http://blog.mclaughlinsoftware.com/2010/02/27/debugging-mysql-procedures/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 05:01:51 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Stored Procedures]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3558</guid>
		<description><![CDATA[In my second database class we focus on PL/SQL but we&#8217;ve begun highlighting the alternatives in MySQL and SQL Server. A student asked how they could debug runtime variable values in a MySQL Stored Procedure (or subroutines according to some documentation). You can see this post for how to create an equivalent solutions for MySQL [...]]]></description>
			<content:encoded><![CDATA[<p>In my second database class we focus on PL/SQL but we&#8217;ve begun highlighting the alternatives in MySQL and SQL Server. A student asked how they could debug runtime variable values in a MySQL Stored Procedure (or subroutines according to some documentation). You can see this post for <a href="http://blog.mclaughlinsoftware.com/2010/06/26/debugging-mysql-function/">how to create an equivalent solutions for MySQL functions</a>.</p>
<p>In Oracle, we debug with the <code>DBMS_OUTPUT</code> package. Packages, like <code>DBMS_OUTPUT</code> hold related functions and procedures, and are a corollary to <code>System.out.println()</code> in Java.</p>
<p>Before you can see the output at the command-line in Oracle (that is if you&#8217;re not using SQL*Developer or Toad), you must set a SQL*Plus environment variable. These variables don&#8217;t exist in MySQL or SQL Server command-line tools because they never served the function of a report writer like SQL*Plus.</p>
<p>You enable output display in Oracle by setting this in SQL*Plus:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">SQL<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SET</span> SERVEROUTPUT <span style="color: #993333; font-weight: bold;">ON</span> SIZE <span style="color: #cc66cc;">1000000</span></pre></div></div>

<p>You can test your anonymous or named block. Since MySQL doesn&#8217;t support anonymous named block, the examples using a trivial procedure that prints <em>Hello World!</em> (orginal, right <img src='http://blog.mclaughlinsoftware.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- Create a procedure in Oracle.</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> PROCEDURE hello_world <span style="color: #993333; font-weight: bold;">IS</span>
BEGIN
  <span style="color: #808080; font-style: italic;">-- Print a word without a line return.</span>
  dbms_output<span style="color: #66cc66;">.</span>put<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Hello '</span><span style="color: #66cc66;">&#41;</span>;
  <span style="color: #808080; font-style: italic;">-- Print the rest of the phrase and a line return.</span>
  dbms_output<span style="color: #66cc66;">.</span>put_line<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'World!'</span><span style="color: #66cc66;">&#41;</span>;
END;
<span style="color: #66cc66;">/</span>
&nbsp;
<span style="color: #808080; font-style: italic;">-- Call the procedure.</span>
EXECUTE hello_world;</pre></td></tr></table></div>

<p>It&#8217;s seems useless to print the output because it should be evident. MySQL procedures are a bit different because there&#8217;s no <code>OR REPLACE</code> syntax. The equivalent to calling the <code>DBMS_OUTPUT</code> package procedures in MySQL is to simply <em>select a string</em>. Now you can do this with or without the <code>FROM dual</code> clause in MySQL, don&#8217;t we wish we could likewise do that in Oracle. <img src='http://blog.mclaughlinsoftware.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- Conditionally drop the procedure.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'DROP PROCEDURE hello_world'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> PROCEDURE <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> hello_world;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Reset the delimiter to write a procedure.</span>
DELIMITER $$
&nbsp;
<span style="color: #808080; font-style: italic;">-- Create a procedure in Oracle.</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> PROCEDURE hello_world<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
BEGIN
  <span style="color: #808080; font-style: italic;">-- Print the phrase and a line return.</span>
  <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'Hello World!'</span>;
END;
$$
&nbsp;
<span style="color: #808080; font-style: italic;">-- Reset the delimiter back to a semicolon to work again.</span>
DELIMITER ;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Call the procedure.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'CALL hello_world'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
CALL hello_world<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>Originally, I tried to keep this short but somebody wanted an example in a loop. Ouch, loops are so verbose in MySQL. Since I was modifying this post, it seemed like a good idea to put down some guidelines for successful development too.</p>
<p><span style="font-size:125%;font-weight:bold">Guidelines for Development of Procedures</span></p>
<p><em><span style="font-size:110%;font-weight:bold">Declaration Guidelines</span></em></p>
<p>The sequencing of components in MySQL procedures is important. Unlike, PL/SQL, there&#8217;s no declaration block, declarations must be at the top of the execution block. They also must appear in the following order:</p>
<ol start="1">
<li>Variable declarations must go first, you can assign initial values with the <code>DEFAULT</code> keyword. While not required, you should:</li>
</ol>
<div style="padding-left:30px">
<ul>
<li>Consider using something like <code>lv_</code> to identify them as <em>local variables</em> for clarity and support of your code.</li>
<li>Consider grouping local variables that relate to handlers at the bottom of the list of variables.</li>
</ul>
</div>
<ol start="2">
<li>After local variables and before <em>handlers</em>, you put your cursor definitions. You should note that MySQL doesn&#8217;t support explicit dynamic cursors, which means you can&#8217;t define one with a formal signature.</li>
<li>Last in your declaration block, you declare your handler events.</li>
</ol>
<p><em><span style="font-size:110%;font-weight:bold">Execution Guidelines</span></em></p>
<ol start="1">
<li>Variable assignments are made one of two ways:</li>
</ol>
<div style="padding-left:30px">
<ul>
<li>You should start each execution block with a <code>START TRANSACTION</code> and then a <code>SAVEPOINT</code>, which ensures the procedure acts like a cohesive programming unit.</li>
<li>You assign a <code>left_operand = right_operand;</code> as a statement.</li>
<li>You use the <code>SELECT column INTO variable;</code> syntax to filter a value through SQL functions and assign the resulting expression to a local variable.</li>
<li>You assign a single row cursor output to variables using a <code>SELECT column INTO variable FROM ...</code>.</li>
</ul>
</div>
<ol start="2">
<li>You must assign values from cursors called in a loop into local variables when you want to use the results in nested SQL statements or loops.</li>
<li>You must reset looping variables, like the <code>fetched</code> control variable at the end of the loop to reuse the handler variable in subsequent loops.</li>
<li>You must assign values to local variables if you want to use them in the exception handler.</li>
<li>If you&#8217;ve started a transaction, don&#8217;t forget to <code>COMMIT</code> your work.</li>
</ol>
<p><em><span style="font-size:110%;font-weight:bold">Exception Guidelines</span></em></p>
<ol start="1">
<li>Leave out the exception handler until you&#8217;ve tested all outcomes, and make sure you document them and add them as potential handlers.</li>
<li>When you deploy exception blocks, they&#8217;re the last element at the bottom of the exception block.</li>
<li>You should consider explicit exception handlers for each error unless the action taken is the same.</li>
<li>You should consider grouping all exception handlers when the action taken is the same.</li>
<li>You should include a <code>ROLLBACK</code> whenever you&#8217;ve performed two or more SQL statements that may modify data.</li>
</ol>
<p>Below is an example for putting debug code inside a loop.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- Conditionally drop a sample table.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'DROP TABLE IF EXISTS sample'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> sample;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Create a table.</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> sample
<span style="color: #66cc66;">&#40;</span> sample_id    INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>
<span style="color: #66cc66;">,</span> sample_msg   VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Insert into sample.</span>
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> sample <span style="color: #66cc66;">&#40;</span>sample_msg<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span>
 <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Message #1'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Message #2'</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Message #3'</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Conditionally drop the procedure.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'DROP PROCEDURE debug_loop'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> PROCEDURE <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> debug_loop;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Reset the delimiter to write a procedure.</span>
DELIMITER $$
&nbsp;
<span style="color: #808080; font-style: italic;">-- Create a procedure in Oracle.</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> PROCEDURE debug_loop<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
BEGIN
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a counter variable. */</span>
  DECLARE lv_counter INT <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare local control loop variables. */</span>
  DECLARE lv_sample_id  INT;
  DECLARE lv_sample_msg VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a local variable for a subsequent handler. */</span>
  DECLARE duplicate_key INT <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #cc66cc;">0</span>;
  DECLARE fetched INT <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #cc66cc;">0</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a SQL cursor fabricated from local variables. */</span>  
  DECLARE sample_cursor CURSOR <span style="color: #993333; font-weight: bold;">FOR</span>
    <span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> sample;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a duplicate key handler */</span>
  DECLARE CONTINUE HANDLER <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">1062</span> <span style="color: #993333; font-weight: bold;">SET</span> duplicate_key <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a not found record handler to close a cursor loop. */</span>
  DECLARE CONTINUE HANDLER <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #993333; font-weight: bold;">NOT</span> FOUND <span style="color: #993333; font-weight: bold;">SET</span> fetched <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Start transaction context. */</span>
  START TRANSACTION;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Set savepoint. */</span>  
  SAVEPOINT all_or_none;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Open a sample cursor. */</span>
  OPEN sample_cursor;
  cursor_sample: LOOP
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Fetch a row at a time. */</span>  
    FETCH sample_cursor
    <span style="color: #993333; font-weight: bold;">INTO</span>  lv_sample_id
    <span style="color: #66cc66;">,</span>     lv_sample_msg;
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Place the catch handler for no more rows found
       immediately after the fetch operation.          */</span>
    <span style="color: #993333; font-weight: bold;">IF</span> fetched <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> THEN LEAVE cursor_sample; END <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
    <span style="color: #808080; font-style: italic;">-- Print the cursor values.</span>
    <span style="color: #993333; font-weight: bold;">SELECT</span> CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Row #'</span><span style="color: #66cc66;">,</span>lv_counter<span style="color: #66cc66;">,</span><span style="color: #ff0000;">' ['</span><span style="color: #66cc66;">,</span>lv_sample_id<span style="color: #66cc66;">,</span><span style="color: #ff0000;">']['</span><span style="color: #66cc66;">,</span>lv_sample_msg<span style="color: #66cc66;">,</span><span style="color: #ff0000;">']'</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Rows&quot;</span>;
&nbsp;
    <span style="color: #808080; font-style: italic;">-- Increment counter variable.</span>
    <span style="color: #993333; font-weight: bold;">SET</span> lv_counter <span style="color: #66cc66;">=</span> lv_counter <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
  END LOOP cursor_sample;
  CLOSE sample_cursor;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* This acts as an exception handling block. */</span>  
  <span style="color: #993333; font-weight: bold;">IF</span> duplicate_key <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> THEN
&nbsp;
    <span style="color: #808080; font-style: italic;">/* This undoes all DML statements to this point in the procedure. */</span>
    ROLLBACK <span style="color: #993333; font-weight: bold;">TO</span> SAVEPOINT all_or_none;
&nbsp;
  END <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
END;
$$
&nbsp;
<span style="color: #808080; font-style: italic;">-- Reset the delimiter back to a semicolon to work again.</span>
DELIMITER ;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Call the procedure.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'CALL debug_loop'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Statement&quot;</span>;
CALL debug_loop<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;</pre></td></tr></table></div>

<p>This post certainly answers the student question. Hopefully, it also helps other who must migrate Oracle skills to MySQL. Since IBM DB2 has introduced a PL/SQL equivalent, wouldn&#8217;t it be nice if Oracle did that for MySQL. Don&#8217;t tell me if you think that&#8217;s a pipe dream, I&#8217;d like to hope for that change.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2010/02/27/debugging-mysql-procedures/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Multi-row Merge in MySQL</title>
		<link>http://blog.mclaughlinsoftware.com/2010/02/24/multi-row-merge-in-mysql/</link>
		<comments>http://blog.mclaughlinsoftware.com/2010/02/24/multi-row-merge-in-mysql/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 15:15:07 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Stored Procedures]]></category>
		<category><![CDATA[pl/sql]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3530</guid>
		<description><![CDATA[After I wrote the post for students on the multiple row MERGE statement for an upload through an external table in Oracle, I thought to check how it might be done with MySQL. More or less because I try to keep track of how things are done in several databases. MySQL&#8217;s equivalent to a MERGE [...]]]></description>
			<content:encoded><![CDATA[<p>After I wrote the post for students on the multiple row <code>MERGE</code> statement for an upload through an external table in Oracle, I thought to check how it might be done with MySQL. More or less because I try to keep track of how things are done in several databases.</p>
<p>MySQL&#8217;s equivalent to a <code>MERGE</code> statement is an <code>INSERT</code> statement with an <code>ON DUPLICATE KEY</code> clause, which I <a href="http://blog.mclaughlinsoftware.com/2009/05/25/mysql-merge-gone-awry/">blogged about a while back</a>. You may also use the <code>REPLACE INTO</code> when you want to <a href="http://blog.mclaughlinsoftware.com/2010/05/14/mysql-replace-into/">merge more than one row</a>. It was interesting to note that you can&#8217;t use an <code>INSERT</code> statement with the <code>ON DUPLICATE KEY</code> clause except in a <code>VALUES</code> clause. While you can do multiple row inserts in the <code>VALUES</code> clause in MySQL, like SQL Server or IBM&#8217;s DB2, you can&#8217;t do it with the <code>ON DUPLICATE KEY</code> clause. There&#8217;s also no support for that clause when you attempt to perform an <code>INSERT</code> statement with a subquery.</p>
<p>The workaround was to write a <em>stored procedure</em> with two cursor loops, explicitly pass the values from the cursor to local variables, and then put the local variables in the <code>VALUES</code> clause. On parity, clearly Oracle&#8217;s <code>MERGE</code> statement (<a href="http://blog.mclaughlinsoftware.com/2010/02/23/merge-statement-for-etl/">shown here</a>) is far superior than MySQL&#8217;s approach.</p>
<p><span style="font-size:125%;font-weight:bold">Demonstration</span></p>
<p>Here are the steps to accomplish an import/upload with the <code>INSERT</code> statement and <code>ON DUPLICATE KEY</code> clause. In this example, you upload data from a flat file, or Comma Separated Value (CSV) file to a denormalized table (actually in unnormalized form). This type of file upload transfers information that doesn&#8217;t have surrogate key values. You have to create those in the scope of the transformation to the normalized tables.</p>
<p style="clear:both">
<p><span style="font-size:115%;font-weight:bold">Step #1 : Position your CSV file in the physical directory</span></p>
<p>After creating the virtual directory, copy the following contents into a file named <code>kingdom_mysql_import.csv</code> in the <code>C:\Data\Download</code> directory or folder. If you have Windows UAC enabled in Windows Vista or 7, you should disable it before performing this step.</p>
<p>Place the following in the <code>kingdom_mysql_import.csv</code> file. The trailing commas are meaningful in MySQL and avoid problems when reading CSV files.</p>
<p style="clear:both">

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">77600</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Peter the Magnificent'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12720320</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12920609</span><span style="color: #66cc66;">,</span>
Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">77600</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Edmund the Just'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12720320</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12920609</span><span style="color: #66cc66;">,</span>
Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">77600</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Susan the Gentle'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12720320</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12920609</span><span style="color: #66cc66;">,</span>
Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">77600</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Lucy the Valiant'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12720320</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">12920609</span><span style="color: #66cc66;">,</span>
Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">42100</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Peter the Magnificent'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310412</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310531</span><span style="color: #66cc66;">,</span>
Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">42100</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Edmund the Just'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310412</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310531</span><span style="color: #66cc66;">,</span>
Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">42100</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Susan the Gentle'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310412</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310531</span><span style="color: #66cc66;">,</span>
Narnia<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">42100</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Lucy the Valiant'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310412</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">15310531</span><span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'King Arthur'</span><span style="color: #66cc66;">,</span>06310310<span style="color: #66cc66;">,</span>06861212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Lionel'</span><span style="color: #66cc66;">,</span>06310310<span style="color: #66cc66;">,</span>06861212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Bors'</span><span style="color: #66cc66;">,</span>06310310<span style="color: #66cc66;">,</span>06351212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Bors'</span><span style="color: #66cc66;">,</span>06400310<span style="color: #66cc66;">,</span>06861212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Galahad'</span><span style="color: #66cc66;">,</span>06310310<span style="color: #66cc66;">,</span>06861212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Gawain'</span><span style="color: #66cc66;">,</span>06310310<span style="color: #66cc66;">,</span>06861212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Tristram'</span><span style="color: #66cc66;">,</span>06310310<span style="color: #66cc66;">,</span>06861212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Percival'</span><span style="color: #66cc66;">,</span>06310310<span style="color: #66cc66;">,</span>06861212<span style="color: #66cc66;">,</span>
Camelot<span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">15200</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'Sir Lancelot'</span><span style="color: #66cc66;">,</span>06700930<span style="color: #66cc66;">,</span>06821212<span style="color: #66cc66;">,</span></pre></div></div>

<p><span style="font-size:115%;font-weight:bold">Step #2 : Connect as the <code>student</code> user</span></p>
<p>Disconnect and connect as the student user, or reconnect as the student user. The reconnect syntax that protects your password is:</p>
<p style="clear:both">

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">mysql <span style="color: #66cc66;">-</span>ustudent <span style="color: #66cc66;">-</span>p</pre></div></div>

<p>Connect to the <code>sampledb</code> database, like so:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">USE</span> sampledb;</pre></div></div>

<p style="clear:both">
<p><span style="font-size:115%;font-weight:bold">Step #3 : Run the script that creates tables and sequences</span></p>
<p>Copy the following into a <code>create_mysql_kingdom_upload.sql</code> file within a directory of your choice. Then, run it as the <code>student</code> account.</p>
<p style="clear:both">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- This enables dropping tables with foreign key dependencies.</span>
<span style="color: #808080; font-style: italic;">-- It is specific to the InnoDB Engine.</span>
<span style="color: #993333; font-weight: bold;">SET</span> FOREIGN_KEY_CHECKS <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>; 
&nbsp;
<span style="color: #808080; font-style: italic;">-- Conditionally drop objects.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'KINGDOM'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Drop Table&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> KINGDOM;
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'KNIGHT'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Drop Table&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> KNIGHT;
&nbsp;
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'KINGDOM_KNIGHT_IMPORT'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Drop Table&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> KINGDOM_KNIGHT_IMPORT;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Create normalized kingdom table.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'KINGDOM'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Create Table&quot;</span>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> kingdom
<span style="color: #66cc66;">&#40;</span> kingdom_id    INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>
<span style="color: #66cc66;">,</span> kingdom_name  VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> population    INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span><span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>INNODB;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Create normalized knight table.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'KNIGHT'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Create Table&quot;</span>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> knight
<span style="color: #66cc66;">&#40;</span> knight_id             INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>
<span style="color: #66cc66;">,</span> knight_name           VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">24</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> kingdom_allegiance_id INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span>
<span style="color: #66cc66;">,</span> allegiance_start_date DATE
<span style="color: #66cc66;">,</span> allegiance_end_date   DATE
<span style="color: #66cc66;">,</span> CONSTRAINT fk_kingdom <span style="color: #993333; font-weight: bold;">FOREIGN</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>kingdom_allegiance_id<span style="color: #66cc66;">&#41;</span>
  <span style="color: #993333; font-weight: bold;">REFERENCES</span> kingdom <span style="color: #66cc66;">&#40;</span>kingdom_id<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>INNODB;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Create external import table in memory only - disappears after rebooting the mysqld service.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'KINGDOM_KNIGHT_IMPORT'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Create Table&quot;</span>;
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> kingdom_knight_import
<span style="color: #66cc66;">&#40;</span> kingdom_name          VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> population            INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span>
<span style="color: #66cc66;">,</span> knight_name           VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">24</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> allegiance_start_date DATE
<span style="color: #66cc66;">,</span> allegiance_end_date   DATE<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>MEMORY;</pre></td></tr></table></div>

<p><span style="font-size:115%;font-weight:bold">Step #4 : Load the data into your target upload table</span></p>
<p>There a number of things that could go wrong but when you choose <code>LOCAL</code> there generally aren&#8217;t any problems. Run the following query from the <code>student</code> account while <em>using</em> the <code>sampledb</code> database, and check whether or not you can access the <code>kingdom_import.csv</code> file.</p>
<p style="clear:both">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">LOAD</span> <span style="color: #993333; font-weight: bold;">DATA</span> <span style="color: #993333; font-weight: bold;">LOCAL</span> <span style="color: #993333; font-weight: bold;">INFILE</span> <span style="color: #ff0000;">'c:/Data/kingdom_mysql_import.csv'</span>
<span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #993333; font-weight: bold;">TABLE</span> kingdom_knight_import
<span style="color: #993333; font-weight: bold;">FIELDS</span> TERMINATED <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">','</span>
<span style="color: #993333; font-weight: bold;">ENCLOSED</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">'&quot;'</span>
<span style="color: #993333; font-weight: bold;">ESCAPED</span> <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\\</span>'</span>
<span style="color: #993333; font-weight: bold;">LINES</span> TERMINATED <span style="color: #993333; font-weight: bold;">BY</span> <span style="color: #ff0000;">'<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>'</span>;</pre></td></tr></table></div>

<p><span style="font-size:115%;font-weight:bold">Step #5 : Create the upload procedure</span></p>
<p>Copy the following into a <code>create_mysql_upload_procedure.sql</code> file within a directory of your choice. You should note that unlike Oracle&#8217;s <code>MERGE</code> statement, this is done with the <code>ON DUPLICATE KEY</code> clause and requires actual values not a source query. This presents few options other than a stored routine, known as a stored procedure. As you can see from the code, there&#8217;s a great deal of complexity to the syntax and a much more verbose implementation than Oracle&#8217;s equivalent PL/SQL.</p>
<p>Then, run it as the <code>student</code> account. As you look at the structure to achieve this simple thing, the long standing complaint about PL/SQL being a verbose language comes to mind. Clearly, stored procedures are new to MySQL but they&#8217;re quite a bit more verbose than PL/SQL.</p>
<p style="clear:both">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- Conditionally drop the procedure.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #ff0000;">'UPLOAD_KINGDOM'</span> <span style="color: #993333; font-weight: bold;">AS</span> <span style="color: #ff0000;">&quot;Drop Procedure&quot;</span>;
<span style="color: #993333; font-weight: bold;">DROP</span> PROCEDURE <span style="color: #993333; font-weight: bold;">IF</span> <span style="color: #993333; font-weight: bold;">EXISTS</span> upload_kingdom;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Reset the execution delimiter to create a stored program.</span>
DELIMITER $$
&nbsp;
<span style="color: #808080; font-style: italic;">-- The parentheses after the procedure name must be there or the MODIFIES SQL DATA raises an compile time exception.</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> PROCEDURE upload_kingdom<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> MODIFIES SQL <span style="color: #993333; font-weight: bold;">DATA</span>
&nbsp;
BEGIN
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare local variables. */</span>
  DECLARE lv_kingdom_id            INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span>;
  DECLARE lv_kingdom_name          VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>;
  DECLARE lv_population            INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span>;
  DECLARE lv_knight_id             INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span>;
  DECLARE lv_knight_name           VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">24</span><span style="color: #66cc66;">&#41;</span>;
  DECLARE lv_kingdom_allegiance_id INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span>;
  DECLARE lv_allegiance_start_date DATE;
  DECLARE lv_allegiance_end_date   DATE;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a handler variables. */</span>
  DECLARE duplicate_key INT <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #cc66cc;">0</span>;
  DECLARE foreign_key   INT <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #cc66cc;">0</span>;
  DECLARE fetched       INT <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #cc66cc;">0</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Cursors must come after variables and before event handlers. */</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a SQL cursor with a left join on the natural key. */</span>  
  DECLARE kingdom_cursor CURSOR <span style="color: #993333; font-weight: bold;">FOR</span>
    <span style="color: #993333; font-weight: bold;">SELECT</span>   <span style="color: #993333; font-weight: bold;">DISTINCT</span>
             k<span style="color: #66cc66;">.</span>kingdom_id
    <span style="color: #66cc66;">,</span>        kki<span style="color: #66cc66;">.</span>kingdom_name
    <span style="color: #66cc66;">,</span>        kki<span style="color: #66cc66;">.</span>population
    <span style="color: #993333; font-weight: bold;">FROM</span>     kingdom_knight_import kki <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> kingdom k
    <span style="color: #993333; font-weight: bold;">ON</span>       kki<span style="color: #66cc66;">.</span>kingdom_name <span style="color: #66cc66;">=</span> k<span style="color: #66cc66;">.</span>kingdom_name
    <span style="color: #993333; font-weight: bold;">AND</span>      kki<span style="color: #66cc66;">.</span>population <span style="color: #66cc66;">=</span> k<span style="color: #66cc66;">.</span>population; 
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a SQL cursor with a join on the natural key. */</span>  
  DECLARE knight_cursor CURSOR <span style="color: #993333; font-weight: bold;">FOR</span>
    <span style="color: #993333; font-weight: bold;">SELECT</span>   kn<span style="color: #66cc66;">.</span>knight_id
    <span style="color: #66cc66;">,</span>        kki<span style="color: #66cc66;">.</span>knight_name
    <span style="color: #66cc66;">,</span>        k<span style="color: #66cc66;">.</span>kingdom_id
    <span style="color: #66cc66;">,</span>        kki<span style="color: #66cc66;">.</span>allegiance_start_date <span style="color: #993333; font-weight: bold;">AS</span> start_date
    <span style="color: #66cc66;">,</span>        kki<span style="color: #66cc66;">.</span>allegiance_end_date <span style="color: #993333; font-weight: bold;">AS</span> end_date
    <span style="color: #993333; font-weight: bold;">FROM</span>     kingdom_knight_import kki <span style="color: #993333; font-weight: bold;">INNER</span> <span style="color: #993333; font-weight: bold;">JOIN</span> kingdom k
    <span style="color: #993333; font-weight: bold;">ON</span>       kki<span style="color: #66cc66;">.</span>kingdom_name <span style="color: #66cc66;">=</span> k<span style="color: #66cc66;">.</span>kingdom_name
    <span style="color: #993333; font-weight: bold;">AND</span>      kki<span style="color: #66cc66;">.</span>population <span style="color: #66cc66;">=</span> k<span style="color: #66cc66;">.</span>population <span style="color: #993333; font-weight: bold;">LEFT</span> <span style="color: #993333; font-weight: bold;">JOIN</span> knight kn 
    <span style="color: #993333; font-weight: bold;">ON</span>       k<span style="color: #66cc66;">.</span>kingdom_id <span style="color: #66cc66;">=</span> kn<span style="color: #66cc66;">.</span>kingdom_allegiance_id
    <span style="color: #993333; font-weight: bold;">AND</span>      kki<span style="color: #66cc66;">.</span>knight_name <span style="color: #66cc66;">=</span> kn<span style="color: #66cc66;">.</span>knight_name
    <span style="color: #993333; font-weight: bold;">AND</span>      kki<span style="color: #66cc66;">.</span>allegiance_start_date <span style="color: #66cc66;">=</span> kn<span style="color: #66cc66;">.</span>allegiance_start_date
    <span style="color: #993333; font-weight: bold;">AND</span>      kki<span style="color: #66cc66;">.</span>allegiance_end_date <span style="color: #66cc66;">=</span> kn<span style="color: #66cc66;">.</span>allegiance_end_date; 
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Event handlers must always be last in the declaration section. */</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a duplicate key handler */</span>
  DECLARE CONTINUE HANDLER <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">1062</span> <span style="color: #993333; font-weight: bold;">SET</span> duplicate_key <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>;
  DECLARE CONTINUE HANDLER <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">1216</span> <span style="color: #993333; font-weight: bold;">SET</span> foreign_key <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Declare a not found record handler to close a cursor loop. */</span>
  DECLARE CONTINUE HANDLER <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #993333; font-weight: bold;">NOT</span> FOUND <span style="color: #993333; font-weight: bold;">SET</span> fetched <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* ---------------------------------------------------------------------- */</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Start transaction context. */</span>
  START TRANSACTION;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Set savepoint. */</span>  
  SAVEPOINT both_or_none;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Open a local cursor. */</span>  
  OPEN kingdom_cursor;
  cursor_kingdom: LOOP
&nbsp;
    FETCH kingdom_cursor
    <span style="color: #993333; font-weight: bold;">INTO</span>  lv_kingdom_id
    <span style="color: #66cc66;">,</span>     lv_kingdom_name
    <span style="color: #66cc66;">,</span>     lv_population;
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Place the catch handler for no more rows found
       immediately after the fetch operation.          */</span>
    <span style="color: #993333; font-weight: bold;">IF</span> fetched <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> THEN LEAVE cursor_kingdom; END <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
    <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> kingdom
    <span style="color: #993333; font-weight: bold;">VALUES</span>
    <span style="color: #66cc66;">&#40;</span> lv_kingdom_id
    <span style="color: #66cc66;">,</span> lv_kingdom_name
    <span style="color: #66cc66;">,</span> lv_population <span style="color: #66cc66;">&#41;</span> 
    <span style="color: #993333; font-weight: bold;">ON</span> DUPLICATE <span style="color: #993333; font-weight: bold;">KEY</span>
    <span style="color: #993333; font-weight: bold;">UPDATE</span> kingdom_name <span style="color: #66cc66;">=</span> lv_kingdom_name;
&nbsp;
  END LOOP cursor_kingdom;
  CLOSE kingdom_cursor;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Reset the continue handler to zero. */</span>
  <span style="color: #993333; font-weight: bold;">SET</span> fetched <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>;  
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Open a local cursor. */</span>  
  OPEN knight_cursor;
  cursor_knight: LOOP
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Fetch records until they're all read, and a NOT FOUND SET is returned. */</span>  
    FETCH knight_cursor
    <span style="color: #993333; font-weight: bold;">INTO</span>  lv_knight_id
    <span style="color: #66cc66;">,</span>     lv_knight_name
    <span style="color: #66cc66;">,</span>     lv_kingdom_allegiance_id
    <span style="color: #66cc66;">,</span>     lv_allegiance_start_date
    <span style="color: #66cc66;">,</span>     lv_allegiance_end_date;
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Place the catch handler for no more rows found
       immediately after the fetch operation.          */</span>
    <span style="color: #993333; font-weight: bold;">IF</span> fetched <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> THEN LEAVE cursor_knight; END <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
    <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> knight
    <span style="color: #993333; font-weight: bold;">VALUES</span>
    <span style="color: #66cc66;">&#40;</span> lv_knight_id
    <span style="color: #66cc66;">,</span> lv_knight_name
    <span style="color: #66cc66;">,</span> lv_kingdom_allegiance_id
    <span style="color: #66cc66;">,</span> lv_allegiance_start_date
    <span style="color: #66cc66;">,</span> lv_allegiance_end_date <span style="color: #66cc66;">&#41;</span> 
    <span style="color: #993333; font-weight: bold;">ON</span> DUPLICATE <span style="color: #993333; font-weight: bold;">KEY</span>
    <span style="color: #993333; font-weight: bold;">UPDATE</span> knight_name <span style="color: #66cc66;">=</span> lv_knight_name;
&nbsp;
  END LOOP cursor_knight;
  CLOSE knight_cursor;
&nbsp;
  <span style="color: #808080; font-style: italic;">/* Reset the continue handler to zero. */</span>
  <span style="color: #993333; font-weight: bold;">SET</span> fetched <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>;  
&nbsp;
  <span style="color: #808080; font-style: italic;">/* ---------------------------------------------------------------------- */</span>
&nbsp;
  <span style="color: #808080; font-style: italic;">/* This acts as an exception handling block. */</span>  
  <span style="color: #993333; font-weight: bold;">IF</span> duplicate_key <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">OR</span> foreign_key <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> THEN
&nbsp;
    <span style="color: #808080; font-style: italic;">/* This undoes all DML statements to this point in the procedure. */</span>
    ROLLBACK <span style="color: #993333; font-weight: bold;">TO</span> SAVEPOINT both_or_none;
&nbsp;
  ELSE
&nbsp;
    <span style="color: #808080; font-style: italic;">/* This commits the writes. */</span>
    COMMIT;
&nbsp;
  END <span style="color: #993333; font-weight: bold;">IF</span>;
&nbsp;
END;
$$
&nbsp;
<span style="color: #808080; font-style: italic;">-- Reset the delimiter to the default.</span>
DELIMITER ;</pre></td></tr></table></div>

<p style="clear:both">
<p><span style="font-size:115%;font-weight:bold">Step #6 : Run the upload procedure</span></p>
<p>You can run the file by calling the <a href="http://michaelmclaughlin.info/db1/lesson-4-inserting-data/transaction-management/">stored procedure</a> built by the script. The procedure ensures that records are inserted or updated into their respective tables.</p>
<p style="clear:both">

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">CALL upload_kingdom;</pre></div></div>

<p style="clear:both">
<p><span style="font-size:115%;font-weight:bold">Step #7 : Test the results of the upload procedure</span></p>
<p>You can test whether or not it worked by running the following queries.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- Check the kingdom table.</span>
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> kingdom;
<span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> knight;</pre></div></div>

<p>It should display the following information:</p>
<p style="clear:both">

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">+------------+--------------+------------+
| kingdom_id | kingdom_name | population |
+------------+--------------+------------+
|          1 | Narnia       |      77600 |
|          2 | Narnia       |      42100 |
|          3 | Camelot      |      15200 |
+------------+--------------+------------+
&nbsp;
+-----------+-------------------------+-----------------------+-----------------------+---------------------+
| knight_id | knight_name             | kingdom_allegiance_id | allegiance_start_date | allegiance_end_date |
+-----------+-------------------------+-----------------------+-----------------------+---------------------+
|         1 | 'Peter the Magnificent' |                     1 | 1272-03-20            | 1292-06-09          |
|         2 | 'Edmund the Just'       |                     1 | 1272-03-20            | 1292-06-09          |
|         3 | 'Susan the Gentle'      |                     1 | 1272-03-20            | 1292-06-09          |
|         4 | 'Lucy the Valiant'      |                     1 | 1272-03-20            | 1292-06-09          |
|         5 | 'Peter the Magnificent' |                     2 | 1531-04-12            | 1531-05-31          |
|         6 | 'Edmund the Just'       |                     2 | 1531-04-12            | 1531-05-31          |
|         7 | 'Susan the Gentle'      |                     2 | 1531-04-12            | 1531-05-31          |
|         8 | 'Lucy the Valiant'      |                     2 | 1531-04-12            | 1531-05-31          |
|         9 | 'King Arthur'           |                     3 | 0631-03-10            | 0686-12-12          |
|        10 | 'Sir Lionel'            |                     3 | 0631-03-10            | 0686-12-12          |
|        11 | 'Sir Bors'              |                     3 | 0631-03-10            | 0635-12-12          |
|        12 | 'Sir Bors'              |                     3 | 0640-03-10            | 0686-12-12          |
|        13 | 'Sir Galahad'           |                     3 | 0631-03-10            | 0686-12-12          |
|        14 | 'Sir Gawain'            |                     3 | 0631-03-10            | 0686-12-12          |
|        15 | 'Sir Tristram'          |                     3 | 0631-03-10            | 0686-12-12          |
|        16 | 'Sir Percival'          |                     3 | 0631-03-10            | 0686-12-12          |
|        17 | 'Sir Lancelot'          |                     3 | 0670-09-30            | 0682-12-12          |
+-----------+-------------------------+-----------------------+-----------------------+---------------------+</pre></div></div>

<p style="clear:both">
<p>You can rerun the procedure to check that it doesn&#8217;t alter any information, then you could add a new knight to test the insertion portion.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2010/02/24/multi-row-merge-in-mysql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP Binding a Wildcard</title>
		<link>http://blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard/</link>
		<comments>http://blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 07:13:31 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3515</guid>
		<description><![CDATA[Somebody asked me about how you bind a parameter in mysqli when a multiple character wildcard needs to be next to the variable value. They&#8217;d found that it worked when creating a SQL statement by concatenation (string gluing), like this: $sql = &#34;SELECT item_title FROM item WHERE item_title LIKE '%&#34;.$title.&#34;%'&#34;; However, they tried to bind [...]]]></description>
			<content:encoded><![CDATA[<p>Somebody asked me about how you bind a parameter in <code>mysqli</code> when a multiple character wildcard needs to be next to the variable value. They&#8217;d found that it worked when creating a SQL statement by concatenation (string gluing), like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT item_title FROM item WHERE item_title LIKE '%&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;%'&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>However, they tried to bind the variable following the same pattern, and found that it failed. They used the following type of syntax:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT item_title FROM item WHERE item_title LIKE '%?%'&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>It raised the following error:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">Warning<span style="color: #339933;">:</span> <span style="color: #990000;">mysqli_stmt_bind_param</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#91;</span><span style="color: #000000; font-weight: bold;">function</span><span style="color: #339933;">.</span>mysqli<span style="color: #339933;">-</span>stmt<span style="color: #339933;">-</span>bind<span style="color: #339933;">-</span>param<span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span> Number of variables doesn<span style="color: #0000ff;">'t match number of parameters in prepared statement in program_name on line #</span></pre></div></div>

<p>The reason is the parser, it expects variables to be independent tokens in the SQL string. You can&#8217;t bind a string into the shell of an apostrophe delimited string. You could naturally, make an assignment to the local PHP variable before binding it to the variable, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'%'</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'%'</span><span style="color: #339933;">;</span></pre></div></div>

<p>It&#8217;s actually a better idea to concatenate the multiple character wildcard operator inside the SQL statement. The correct syntax requires that you use the <code>CONCAT()</code> function. You could reset to use piped concatenation but generally you should avoid that on the MySQL platform (see <a href="http://blog.mclaughlinsoftware.com/2009/03/09/sql-concatenation-blues/">this post</a> for an explanation of SQL concatenation on Oracle, MySQL, and SQL Server).</p>
<p>This is the required statement when using a MySQL database:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT item_title FROM item WHERE item_title LIKE CONCAT('%',?,'%')&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<div class="dropdownbox" style="padding-left:20px;background:#FFFFFF">
<p title="Click to see content ..." class="dropdownclick"><strong><em><span style="font-size:125%">Complete Code Sample</span></em></strong> <span>&darr;</span></p>
<p style="clear: both">
Expand this section to see the complete working code sample.</p>
<div>
<p>The first component for this program is an include file for the database credentials:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #666666; font-style: italic;">// Connection variables.</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HOSTNAME'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;localhost&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'USERNAME'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;student&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PASSWORD'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;student&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DATABASE'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;sampledb&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Once you&#8217;ve placed the credentials in your directory, you can put this in the same directory and then call it from your browser. At least, you can provided you&#8217;ve created the user with the required password, and the database on the standard <code>3306</code> port.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #666666; font-style: italic;">// Set database credentials.</span>
  <span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;MySQLCredentials.inc&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Return successful attempt to connect to the database.</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">mysqli_connect</span><span style="color: #009900;">&#40;</span>HOSTNAME<span style="color: #339933;">,</span>USERNAME<span style="color: #339933;">,</span>PASSWORD<span style="color: #339933;">,</span>DATABASE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Print user message.</span>
    <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Sorry! The connection to the database failed. Please try again later.&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Assign the OCI error and format double and single quotes.</span>
    <span style="color: #b1b100;">print</span> <span style="color: #990000;">mysqli_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Kill the resource.</span>
    <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Declare input variables.</span>
    <span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #000088;">$title</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;RoboCop&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    query_insert<span style="color: #009900;">&#40;</span><span style="color: #000088;">$title</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Query results afret an insert.</span>
  <span style="color: #000000; font-weight: bold;">function</span> query_insert<span style="color: #009900;">&#40;</span><span style="color: #000088;">$title</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Return successful attempt to connect to the database.</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$c</span>  <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">mysqli_connect</span><span style="color: #009900;">&#40;</span>HOSTNAME<span style="color: #339933;">,</span>USERNAME<span style="color: #339933;">,</span>PASSWORD<span style="color: #339933;">,</span>DATABASE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">// Print user message.</span>
      <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Sorry! The connection to the database failed. Please try again later.&quot;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Assign the OCI error and format double and single quotes.</span>
      <span style="color: #b1b100;">print</span> <span style="color: #990000;">mysqli_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Kill the resource.</span>
      <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Initialize a statement in the scope of the connection.</span>
      <span style="color: #000088;">$stmt</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysqli_stmt_init</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Declare a SQL SELECT statement returning a CLOB.</span>
      <span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT item_title FROM item WHERE item_title LIKE CONCAT('%',?,'%')&quot;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Prepare statement.</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_stmt_prepare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">mysqli_stmt_bind_param</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;s&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$title</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Execute it and print success or failure message.</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_stmt_execute</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// Store result.</span>
          <span style="color: #990000;">mysqli_stmt_store_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// Bind result to local variable.</span>
          <span style="color: #990000;">mysqli_stmt_bind_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #000088;">$item_title</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// Open HTML table and print header.</span>
          <span style="color: #000088;">$out</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;table border=&quot;1&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot;&gt;'</span><span style="color: #339933;">;</span>
          <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;tr&gt;'</span><span style="color: #339933;">;</span>
          <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;th align=&quot;center&quot; style=&quot;font-weight:bold;padding:2px;margin:1px;background:#8DB3E2;width:300px&quot;&gt;Item Title&lt;/th&gt;'</span><span style="color: #339933;">;</span>
          <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;/tr&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// Read result.</span>
          <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_stmt_fetch</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;tr&gt;'</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;td style=&quot;padding:2px;margin:1px;background:#DBE5F1;&quot;&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$item_title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/td&gt;'</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;/tr&gt;'</span><span style="color: #339933;">;</span>
          <span style="color: #009900;">&#125;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// Close the HTML table.</span>
          <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;/table&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
          <span style="color: #666666; font-style: italic;">// Print the HTML table.</span>
          <span style="color: #b1b100;">print</span> <span style="color: #000088;">$out</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Free system resources.</span>
      <span style="color: #990000;">mysqli_stmt_free_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Disconnect from database.</span>
      <span style="color: #990000;">mysqli_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2010/02/21/php-binding-a-wildcard/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What a VMWare Thrill &#8230;</title>
		<link>http://blog.mclaughlinsoftware.com/2010/02/06/what-a-vmware-thrill/</link>
		<comments>http://blog.mclaughlinsoftware.com/2010/02/06/what-a-vmware-thrill/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 17:49:23 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[Red Hat]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[VMWare]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3473</guid>
		<description><![CDATA[I&#8217;d upgraded from VMWare Fusion 2 to 3 and taken care of most instances. A NASTY surprise awaited me when I tried to upgrade my Linux installations this morning. You MUST to uninstall VMWare tools from your repository of Linux operating systems before upgrading your VMWare Fusion or ESX server. If you don&#8217;t, you can&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;d upgraded from VMWare Fusion 2 to 3 and taken care of most instances. A <span style="color:red"><em><strong>NASTY surprise</strong></em></span> awaited me when I tried to upgrade my Linux installations this morning.</p>
<p>You <em><strong>MUST</strong></em> to uninstall VMWare tools from your repository of Linux operating systems before upgrading your VMWare Fusion or ESX server. If you don&#8217;t, you can&#8217;t access the console because the drivers make the console look like this:</p>
<p><a href="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/RedHatZappedbyVMWare.png"><img src="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/RedHatZappedbyVMWare-300x225.png" alt="" title="RedHatZappedbyVMWare" width="300" height="225" class="aligncenter size-medium wp-image-3474" /></a></p>
<p>Perhaps I missed <a href="http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&#038;cmd=displayKC&#038;externalId=998">this note</a> when, as an early adopted I opted to move straight to VMWare Fusion 3. I would have complied with these instructions to avoid this headache.</p>
<p>All that&#8217;s required now, is that: (a) I export 500 GBs worth of virtual machines to another machine running VMWare Fusion 2; (b) Individually start each machine and run the uninstall VMWare Tools command individually; and, (c) Shutdown and reposition all virtual machines on the original server.</p>
<p>As stated in the note, the command to remove it is:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>vmware-tools-uninstall.pl</pre></div></div>

<p>Click on the note in the event the link fails to resolve, which would mean the note vanishes into oblivion some day in the future &#8230; </p>
<p><a href="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/VMWareZappedNote.png"><img src="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/VMWareZappedNote-300x187.png" alt="" title="VMWareZappedNote" width="300" height="187" class="aligncenter size-medium wp-image-3475" /></a></p>
<p>While I&#8217;ve another machine that&#8217;s not yet upgraded, this is a major inconvenience. It&#8217;s a shame that the Linux components don&#8217;t install automatically. It&#8217;s a shame that the install didn&#8217;t say something like, <em>&#8220;Don&#8217;t do this if you&#8217;ve Linux virtual machines, unless you&#8217;ve removed their VMWare Tools installation.&#8221;</em></p>
<p>Another word to the wise, you don&#8217;t get the Linux Tools automatically when you download the product. The software prompts you to download the additional components when you attempt to launch a Linux environment. A cruel irony since by the time you see the prompt, you can&#8217;t! This is a change from the prior upgrade process.</p>
<p>Yes, haste makes waste but now I know. In the future, treat all VMWare upgrades like those from Microsoft test, re-test, re-authenticate in a small way before upgrading. Do you think VMWare really want to send that message to its customer base?</p>
<p><a href="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/RedHatSessionManagement.png"><img src="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/RedHatSessionManagement.png" alt="" title="RedHatSessionManagement" width="93" height="36" class="alignright size-full wp-image-3486" /></a>I got back to this tonight, and thanks to Red Hat&#8217;s Session Manager I was able to fix the Red Hat VMs. Launching it, I simply switched to the Failsafe Terminal and ran the following command, as per the note:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># /usr/bin/vmware-uninstall.pl</span></pre></div></div>

<p style="clear:both">
<p><a href="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/RedHatFailsafeTerminal.png"><img src="http://blog.mclaughlinsoftware.com/wp-content/uploads/2010/02/RedHatFailsafeTerminal.png" alt="" title="RedHatFailsafeTerminal" style="border:none" width="264" height="181" class="aligncenter size-full wp-image-3487" /></a></p>
<p>After that, I rebooted. Then, installed (mounted the VMWare Tools disk) from the VMWare Fusion menu. Opening a terminal as <code>root</code>, I then re-installed and configured VMWare Fusion. Those are done. As more time allows, I&#8217;ll update about the others.</p>
<p>I&#8217;m now reconfiguring the network since the VMWare Fusion 2 bridged at a 172.16.153 subdomain and VMWare Fusion 3 bridges at a 172.16.123 subdomain.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2010/02/06/what-a-vmware-thrill/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The ereg() function is gone</title>
		<link>http://blog.mclaughlinsoftware.com/2009/12/29/the-ereg-function-is-gone/</link>
		<comments>http://blog.mclaughlinsoftware.com/2009/12/29/the-ereg-function-is-gone/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 08:03:30 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=3381</guid>
		<description><![CDATA[Alas, poor ereg() I abused you well. PHP 5.3 has deprecated ereg() and now we must move forward with preg_match(). Along with that change, somebody asked me to show how to upload images to the file system as opposed to the database. Personally, I think they should be stored in the database. With my bias [...]]]></description>
			<content:encoded><![CDATA[<p>Alas, poor <code>ereg()</code> I abused you well. PHP 5.3 has deprecated <code>ereg()</code> and now we must move forward with <code>preg_match()</code>. Along with that change, somebody asked me to show how to upload images to the file system as opposed to the database. Personally, I think they should be stored in the database.</p>
<p>With my bias toward databases, I threw in a virtual directory mapping in a MySQL database because it doesn&#8217;t natively support an Oracle equivalent <code>BFILE</code> data type. You can see <a href="http://blog.mclaughlinsoftware.com/plsql-programming/how-to-return-a-fully-qualified-bfile-file-name-from-a-function/">this older post</a> how to use the <code>DBA_DIRECTORIES</code> view in Oracle to mimic this behavior.</p>
<p>Naturally, MySQL is the preferred database of the person asking the question. You could also implement this exactly the same in Oracle but you really don&#8217;t want to do so. Using Oracle&#8217;s <em>virtual directories</em> has it&#8217;s own pre-built set of security features. They provide a more robust solution.  </p>
<p>The code is presented as follows (<a href="http://blog.mclaughlinsoftware.com/2009/05/24/mysql-installation-and-more/">setup for MySQL instructions</a>):</p>
<ol start="1">
<li>Create and seed the <code>DIRECTORY</code> table in MySQL:</li>
</ol>
<div style="margin-left:30px">

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- Create a directory table.</span>
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> directory
<span style="color: #66cc66;">&#40;</span> directory_id   int <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>
<span style="color: #66cc66;">,</span> virtual_name   varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> directory_name varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">60</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;
&nbsp;
<span style="color: #808080; font-style: italic;">-- Seed the table with a virtual directory mapping.</span>
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> directory <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'CMS_IMAGES'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'C:<span style="color: #000099; font-weight: bold;">\\</span>Data'</span> <span style="color: #66cc66;">&#41;</span>;</pre></div></div>

</div>
<ol start="2">
<li>Create a <code>MySQLCredentials.inc</code> <em>credentails</em> file for inclusion in the PHP program:</li>
</ol>
<div style="margin-left:30px">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #666666; font-style: italic;">// Connection variables.</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'HOSTNAME'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;localhost&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'USERNAME'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;student&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'PASSWORD'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;student&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #990000;">define</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'DATABASE'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;sampledb&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

</div>
<ol start="3">
<li>Create the PHP uploading program, named <code>MySQLFileUpload.php</code>:</li>
</ol>
<div style="margin-left:30px">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
  <span style="color: #666666; font-style: italic;">// Set database credentials.</span>
  <span style="color: #b1b100;">include_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;MySQLCredentials.inc&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Declare input variables.</span>
  <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> ? <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">:</span> <span style="color: #cc66cc;">1021</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Upload a file to server in a mapped physical drive location.</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>process_uploaded_file<span style="color: #009900;">&#40;</span>map_virtual_directory<span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Successfully Uploaded the file.&lt;br /&gt;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Map a virtual directory to a physical directory.</span>
  <span style="color: #000000; font-weight: bold;">function</span> map_virtual_directory<span style="color: #009900;">&#40;</span><span style="color: #000088;">$virtual</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Return successful attempt to connect to the database.</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #000088;">$c</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #990000;">mysqli_connect</span><span style="color: #009900;">&#40;</span>HOSTNAME<span style="color: #339933;">,</span>USERNAME<span style="color: #339933;">,</span>PASSWORD<span style="color: #339933;">,</span>DATABASE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Print user message.</span>
      <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Sorry! The connection to the database failed. Please try again later.&quot;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Return error message.</span>
      <span style="color: #b1b100;">print</span> <span style="color: #990000;">mysqli_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Kill the resource.</span>
      <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Initialize a statement in the scope of the connection.</span>
      <span style="color: #000088;">$stmt</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysqli_stmt_init</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Declare a case insensitive dynamic SQL statement.</span>
      <span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SELECT directory_name FROM directory WHERE virtual_name = UCASE(?)&quot;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Prepare the statement.</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_stmt_prepare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Bind the input parameter to the prepared statement.</span>
        <span style="color: #990000;">mysqli_stmt_bind_param</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'s'</span><span style="color: #339933;">,</span><span style="color: #000088;">$virtual</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">// Execute the prepared statement.</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_stmt_execute</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// Bind the result to a local variable.</span>
          <span style="color: #990000;">mysqli_stmt_bind_result</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #000088;">$directory</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// FetchPrepare statement and link it to a connection.</span>
          <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_stmt_fetch</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #000088;">$directory</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">else</span>
          <span style="color: #666666; font-style: italic;">// Return error message.</span>
          <span style="color: #b1b100;">print</span> <span style="color: #990000;">mysqli_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
      <span style="color: #b1b100;">else</span>
        <span style="color: #666666; font-style: italic;">// Return error message.</span>
        <span style="color: #b1b100;">print</span> <span style="color: #990000;">mysqli_error</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
          <span style="color: #666666; font-style: italic;">// Disconnect from database.</span>
      <span style="color: #990000;">mysqli_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$c</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Manage file upload.</span>
  <span style="color: #000000; font-weight: bold;">function</span> process_uploaded_file<span style="color: #009900;">&#40;</span><span style="color: #000088;">$directory</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">/* Assume the application may allow a virtual directory with a trailing backslash or forward
       slash to be stored in the database, and manage both scenarios across Windows and Linux. */</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;.Win32.&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;SERVER_SOFTWARE&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/\b<span style="color: #000099; font-weight: bold;">\\</span>\/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$directory</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/\b\//&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$directory</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$directory</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$directory</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$directory</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$directory</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$directory</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>&quot;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
      <span style="color: #b1b100;">else</span> <span style="color: #000088;">$directory</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$directory</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>&quot;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">else</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/\b\//&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$directory</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #000088;">$directory</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$directory</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$directory</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">else</span>
        <span style="color: #000088;">$directory</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$directory</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;/&quot;</span><span style="color: #339933;">;</span>  
&nbsp;
    <span style="color: #666666; font-style: italic;">// Check for, move uploaded file, and confirm processing.</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_uploaded_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'userfile'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tmp_name'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Move temporary cache into a file directory with the uploaded file name.</span>
      <span style="color: #990000;">move_uploaded_file</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'userfile'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tmp_name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #000088;">$directory</span><span style="color: #339933;">.</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'userfile'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Remove this from real code, it's here for example only. ;-)</span>
      <span style="color: #b1b100;">print</span> <span style="color: #0000ff;">&quot;Uploaded [&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'userfile'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;] to&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$directory</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;&lt;br /&gt;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// Return true to encapsulate the functional logic on success.</span>
	    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">else</span>
      <span style="color: #666666; font-style: italic;">// Return false to encapsulate the functional logic on failure.</span>
	    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

</div>
<ol start="4">
<li>Create a web page to test it:</li>
</ol>
<div style="margin-left:30px">

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;html&gt;
&lt;head&gt;
&lt;title&gt;
  UploadFileFormMySQL.htm
&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;form id=&quot;uploadForm&quot;
      action=&quot;MySQLFileUpload.php&quot;
      enctype=&quot;multipart/form-data&quot;
      method=&quot;post&quot;&gt;
  &lt;table border=0 cellpadding=0 cellspacing=0&gt;
    &lt;tr&gt;
      &lt;td width=125&gt;Item Number&lt;/td&gt;
      &lt;td&gt;
        &lt;input id=&quot;id&quot; name=&quot;id&quot; type=&quot;text&quot;&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td width=125&gt;Select File&lt;/td&gt;
      &lt;td&gt;
        &lt;input id=&quot;uploadfilename&quot; name=&quot;userfile&quot; type=&quot;file&quot;&gt;
      &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td width=125&gt;Click Button to&lt;/td&gt;
      &lt;td&gt;&lt;input type=&quot;submit&quot; value=&quot;Upload File&quot;&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</pre></td></tr></table></div>

</div>
<p>Hope this helps a few folks. I imagine that the prepared statement with bound variables may help a few folks because it&#8217;s not found (at writing) on the <code>php.net</code> web site.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2009/12/29/the-ereg-function-is-gone/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Toad for MySQL Freeware</title>
		<link>http://blog.mclaughlinsoftware.com/2009/07/11/toad-for-mysql-freeware/</link>
		<comments>http://blog.mclaughlinsoftware.com/2009/07/11/toad-for-mysql-freeware/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 23:03:06 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[Microsoft Vista]]></category>
		<category><![CDATA[Microsoft XP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=2888</guid>
		<description><![CDATA[While SQL Developer is a nice tool and free, Toad is still an awesome development platform, albeit for Windows. In fact, it was annoying to have to install the Microsoft .NET Framework before installing it. It is free for MySQL! Since my students have to do all their work in Oracle and then port it [...]]]></description>
			<content:encoded><![CDATA[<p>While SQL Developer is a nice tool and free, Toad is still an awesome development platform, albeit for Windows. In fact, it was annoying to have to install the Microsoft .NET Framework before installing it. It is free for MySQL!</p>
<p>Since my students have to do all their work in Oracle and then port it to MySQL, I demonstrate Quest&#8217;s Toad for MySQL&#8217;s at the end of the term. I don&#8217;t want them to leverage the automatic ERD diagramming while they&#8217;re learning how to do it.</p>
<p>There&#8217;s only one real trick to making automatic ERD diagramming work. That trick requires that you write your loading scripts for the Inno DB and use referential integrity constraints. My <a href='http://blog.mclaughlinsoftware.com/wp-content/uploads/2009/07/VideoStoreRI_1.zip'>sample Video Store scripts</a> for my database class are updated for MySQL referential integrity. </p>
<p><a href="http://blog.mclaughlinsoftware.com/wp-content/uploads/2009/07/ToadERDModel.png"><img src="http://blog.mclaughlinsoftware.com/wp-content/uploads/2009/07/ToadERDModel.png" alt="ToadERDModel" title="ToadERDModel" width="556" height="181" class="aligncenter size-full wp-image-2889" /></a></p>
<p>Unlike the friendly <code>CASCADE CONSTRAINTS</code> clause you can use in Oracle, MySQL won&#8217;t let you create a re-runnable script with only DDL statements. Actually, the constraint comes from the InnoDB engine. You must issue a specialized InnoDB command before running your script:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>11
12
13
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">-- This enables dropping tables with foreign key dependencies.</span>
<span style="color: #808080; font-style: italic;">-- It is specific to the InnoDB Engine.</span>
<span style="color: #993333; font-weight: bold;">SET</span> FOREIGN_KEY_CHECKS <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">0</span>;</pre></td></tr></table></div>

<p>Primary keys are a bit different from Oracle and it appears you can&#8217;t name them, at least I couldn&#8217;t see how to do it. Here&#8217;s an example of primary and foreign key constraints in MySQL. The primary key is inline and the foreign key constraints are out of line. This example from the downloadable scripts uses self referencing foreign key constraints.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
</pre></td><td class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> system_user
<span style="color: #66cc66;">&#40;</span> system_user_id              INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span>
<span style="color: #66cc66;">,</span> system_user_name            CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>     <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">,</span> system_user_group_id        INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">,</span> system_user_type            INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">,</span> first_name                  CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> middle_name                 CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> last_name                   CHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">20</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> created_by                  INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">,</span> creation_date               DATE         <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">,</span> last_updated_by             INT <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">,</span> last_update_date            DATE         <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>
<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">KEY</span> system_user_fk1 <span style="color: #66cc66;">&#40;</span>created_by<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> CONSTRAINT system_user_fk1 <span style="color: #993333; font-weight: bold;">FOREIGN</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>created_by<span style="color: #66cc66;">&#41;</span>
  <span style="color: #993333; font-weight: bold;">REFERENCES</span> system_user <span style="color: #66cc66;">&#40;</span>system_user_id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">KEY</span> system_user_fk2 <span style="color: #66cc66;">&#40;</span>last_updated_by<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span> CONSTRAINT system_user_fk2 <span style="color: #993333; font-weight: bold;">FOREIGN</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>last_updated_by<span style="color: #66cc66;">&#41;</span>
  <span style="color: #993333; font-weight: bold;">REFERENCES</span> system_user <span style="color: #66cc66;">&#40;</span>system_user_id<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB <span style="color: #993333; font-weight: bold;">DEFAULT</span> CHARSET<span style="color: #66cc66;">=</span>latin1;</pre></td></tr></table></div>

<p>Once installed (<a href="http://blog.mclaughlinsoftware.com/mysql-databas/toad-for-mysql-freeware/">instructions are here</a>) and connected to the MySQL database, you simply click the ERD icon in the top panel and drag the tables onto the canvas. You&#8217;ll see something like this (by the way click on the image to see its full size):</p>
<p><a href="http://blog.mclaughlinsoftware.com/wp-content/uploads/2009/07/ToadQuery.png"><img src="http://blog.mclaughlinsoftware.com/wp-content/uploads/2009/07/ToadQuery.png" alt="ToadQuery" title="ToadQuery" width="520" height="377" class="aligncenter size-full wp-image-2891" /></a></p>
<p>Have fun with it. It&#8217;ll be interesting to see how Oracle positions MySQL when they own it. My hunch is that they&#8217;ll continue to sell it and provide it as an open source product.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2009/07/11/toad-for-mysql-freeware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP for loading a BLOB</title>
		<link>http://blog.mclaughlinsoftware.com/2009/07/09/php-for-loading-a-blob/</link>
		<comments>http://blog.mclaughlinsoftware.com/2009/07/09/php-for-loading-a-blob/#comments</comments>
		<pubDate>Thu, 09 Jul 2009 08:57:56 +0000</pubDate>
		<dc:creator>maclochlainn</dc:creator>
				<category><![CDATA[LAMP]]></category>
		<category><![CDATA[MAMP]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.mclaughlinsoftware.com/?p=2824</guid>
		<description><![CDATA[Sometimes you chalk something up as straightforward because you&#8217;ve done it a while. I did that in a lab assignment recently. It asked my students to upload a large text file and image to the MySQL database, store them in a TEXT and MEDIUMBLOB column, and read them back out of the database, like this: [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you chalk something up as straightforward because you&#8217;ve done it a while. I did that in a lab assignment recently. It asked my students to upload a large text file and image to the MySQL database, store them in a <code>TEXT</code> and <code>MEDIUMBLOB</code> column, and read them back out of the database, like this:</p>
<p><a href="http://blog.mclaughlinsoftware.com/wp-content/uploads/2009/07/mysql_lob4.png"><img src="http://blog.mclaughlinsoftware.com/wp-content/uploads/2009/07/mysql_lob4.png" alt="mysql_lob4" title="mysql_lob4" style="border:none" width="555" height="516" class="aligncenter size-full wp-image-2821" /></a></p>
<p>The trick was that I wanted them to read the file into a string and then load the string. There wasn&#8217;t a single code example to do this out there, except some that might exist behind an account and credit card payment. I put together a complete example like the <a href="http://blog.mclaughlinsoftware.com/php-programming/oracle-lob-processing/">Oracle LOB processing page</a>. You can find it here in the <a href="http://blog.mclaughlinsoftware.com/php-programming/mysql-textblob-processing/">MySQL LOB processing blog page</a>. More or less, it shows you how to stream an image into a MySQL database in chunks (I chose 8 K chunks).</p>
<p>The general tricks to upload a string require you enclose to enclose them with the <code>addslashes()</code> function before assigning a binary stream to a variable, then <code>stripslashes()</code> function by segment before you load it to the database. You really don&#8217;t need to do that. <em>It&#8217;s a myth</em>. The binary stream doesn&#8217;t require that extra handling. In fact, you can corrupt certain images when you use the <code>addslashes()</code> and <code>stripslashes()</code> functions; they should be avoided in this context.</p>
<p>You should do it in streams (at least when they&#8217;re larger than 1 MB), I chose the procedural <code>mysqli</code> to demonstrate it because there wasn&#8217;t an example that I or my students could find on the <em>web</em>. Just for information, some laptops don&#8217;t have the resources to accommodate <code>LARGEBLOB</code> datatypes on the Windows OS. The <code>BLOB</code> or <code>MEDIUMBLOB</code> should work fine, especially for this little example.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>46
47
48
49
50
51
52
53
54
55
56
57
58
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #666666; font-style: italic;">// Declare a PL/SQL execution command.</span>
    <span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;UPDATE item SET item_blob = ? WHERE item_id =  ?&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Prepare statement and link it to a connection.</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">mysqli_stmt_prepare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #000088;">$sql</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #990000;">mysqli_stmt_bind_param</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;bi&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$item_blob</span><span style="color: #339933;">,</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$start</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$chunk</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">8192</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$start</span> <span style="color: #339933;">&lt;</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$item_blob</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #990000;">mysqli_send_long_data</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$stmt</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$item_blob</span><span style="color: #339933;">,</span><span style="color: #000088;">$start</span><span style="color: #339933;">,</span><span style="color: #000088;">$chunk</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$start</span> <span style="color: #339933;">+=</span> <span style="color: #000088;">$chunk</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>You can find the code in that blog page referenced. Hope it helps some folks.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.mclaughlinsoftware.com/2009/07/09/php-for-loading-a-blob/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
