<?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>VerySimple &#187; SQL</title>
	<atom:link href="http://verysimple.com/category/sql/feed/" rel="self" type="application/rss+xml" />
	<link>http://verysimple.com</link>
	<description>Custom Software Development</description>
	<lastBuildDate>Wed, 08 Sep 2010 17:15:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>sqlite lpad and rpad functionality</title>
		<link>http://verysimple.com/2010/01/12/sqlite-lpad-rpad-function/</link>
		<comments>http://verysimple.com/2010/01/12/sqlite-lpad-rpad-function/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 04:23:30 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/?p=483</guid>
		<description><![CDATA[sqlite is missing several basic database features compared to typical SQL servers and unfortunately padding is one of them.  For a most situations though, you can use a simple hack to get the same functionality.   This trick uses a combination of concatenation and substr: -- the statement below is almost the same as -- select [...]]]></description>
			<content:encoded><![CDATA[<p>sqlite is missing several basic database features compared to typical SQL servers and unfortunately padding is one of them.  For a most situations though, you can use a simple hack to get the same functionality.   This trick uses a combination of concatenation and substr:</p>
<pre>-- the statement below is almost the same as
-- select lpad(mycolumn,'0',10) from mytable

select substr('0000000000' || mycolumn, -10, 10) from mytable

-- the statement below is almost the same as
-- select rpad(mycolumn,'0',10) from mytable

select substr(mycolumn || '0000000000', 1, 10) from mytable
</pre>
<p>The statement is fairly self-explanatory, but in case it doesn&#8217;t make sense we&#8217;re simply adding a big long string of characters to the original value and then truncating it down to the desired length.  The string used for concatenation has to be at least the same length that you are padding &#8211; 10 characters is used in this example (&#8217;0000000000&#8242;).</p>
<p>In most cases this workaround produces the same results as lpad/rpad except in the case where the length of your original value is greater than the length that you are padding.  In which case the original value would get truncated.  Usually when you are padding you know what the maximum length of the column anyway.</p>
<p>If you know of a more efficient technique, please post a comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2010/01/12/sqlite-lpad-rpad-function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing LAMP stack on OSX 10.6 Snow Leopard</title>
		<link>http://verysimple.com/2009/09/18/installing-lamp-stack-on-osx-10-6-snow-leopard/</link>
		<comments>http://verysimple.com/2009/09/18/installing-lamp-stack-on-osx-10-6-snow-leopard/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 21:55:19 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OSX]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/?p=414</guid>
		<description><![CDATA[I&#8217;m setting up a new machine and found a great tutorial written by Josh Lockhart on getting a PHP web development environment up and running on Snow Leopard.  This goes through almost everything to be up and running for a typical LAMP stack with unit testing using all of the default services. Josh&#8217;s instructions include [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m setting up a new machine and found a great tutorial written by Josh Lockhart on <a href="http://www.newmediacampaigns.com/page/install-pear-phpunit-xdebug-on-macosx-snow-leopard" target="_blank">getting a PHP web development environment up and running on Snow Leopard</a>.  This goes through almost everything to be up and running for a typical LAMP stack with unit testing using all of the default services.</p>
<p>Josh&#8217;s instructions include everything that I need except mcrypt.  Luckily Michael Gracie has provided a walk-through for <a href="http://michaelgracie.com/2009/09/23/plugging-mcrypt-into-php-on-mac-os-x-snow-leopard-10.6.1/" target="_blank">installing mcrypt on Snow Leopard</a> which involves re-compiling some things, but isn&#8217;t as tough as it first appears.</p>
<p>After getting PHP and mcrypt going, the last step for me is setting up MySQL which has some caveats on OSX.  The main problem is that the MySQL installer places the mysql.sock file in a non-standard place and so you have to either <a href="http://www.verysimple.com/blog/2009/01/07/php-on-os-cant-connect-to-local-mysql-server-through-socket-varmysqlmysqlsock/">create a link or alter your php.ini file</a> before PHP will be able to talk to MySQL.  (If you get <em>&#8220;Can’t connect to local MySQL server through socket ‘/var/mysql/mysql.sock’</em>&#8221; or  “<em>No such file or directory</em>” when calling mysql_connect, then this is the problem)</p>
<p><span id="more-414"></span></p>
<p>After completing the steps on Josh&#8217;s &amp; Michael&#8217;s pages and running the MySQL installation package, here are the additional steps that I like to take to get my local environment configured:</p>
<p><strong>Edit /private/etc/php.ini</strong></p>
<p>display_errors = On<br />
mysql.default_socket = /tmp/mysql.sock<br />
pdo_mysql.default_socket=/tmp/mysql.sock<br />
date.timezone = &#8216;America/Chicago&#8217;</p>
<p><strong>Edit /private/etc/apache2/httpd.conf</strong></p>
<p>DocumentRoot &#8220;/Users/jason/Sites&#8221;</p>
<p><strong>Edit /private/etc/apache2/users/jason.conf</strong></p>
<p>Append <em>FollowSymLinks</em> to the Options</p>
<p>I also like to change the permissions on php.ini and httpd.conf to allow my user account edit permissions and create an alias to those two files somewhere easy to get to.</p>
<p>Installing <a href="http://www.mamp.info" target="_blank">MAMP</a> is probably easier, but for some reason I prefer using all of the services that are pre-bundled with OSX.  Also Snow Leopard includes PHP 5.3 which led me to find a couple of deprecated functions in some of our libraries.</p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2009/09/18/installing-lamp-stack-on-osx-10-6-snow-leopard/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PHP on OSX: Can&#039;t connect to local MySQL server through socket &#039;/var/mysql/mysql.sock&#039;</title>
		<link>http://verysimple.com/2009/01/07/php-on-os-cant-connect-to-local-mysql-server-through-socket-varmysqlmysqlsock/</link>
		<comments>http://verysimple.com/2009/01/07/php-on-os-cant-connect-to-local-mysql-server-through-socket-varmysqlmysqlsock/#comments</comments>
		<pubDate>Wed, 07 Jan 2009 21:59:29 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[*NIX]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[OSX]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/2009/01/07/osx-php-cant-connect-to-local-mysql-server-through-socket-varmysqlmysqlsock/</guid>
		<description><![CDATA[When installing PHP and MySQL on OSX  you may get the error Can&#8217;t connect to local MySQL server through socket &#8216;/var/mysql/mysql.sock&#8217;.  Or you may also get &#8220;No such file or directory&#8221; when calling mysql_connect from a PHP page.  This occurs because PHP is looking for the file mysql.sock in it&#8217;s typical installation location of /var/mysql/mysql.sock. [...]]]></description>
			<content:encoded><![CDATA[<p>When installing PHP and MySQL on OSX  you may get the error <em>Can&#8217;t connect to local MySQL server through socket &#8216;/var/mysql/mysql.sock&#8217;</em>.   Or you may also get &#8220;<em>No such file or directory</em>&#8221; when calling mysql_connect from a PHP page.  This occurs because PHP is looking for the file mysql.sock in it&#8217;s typical installation location of /var/mysql/mysql.sock.  However the MySQL OSX installer actually puts the file in /tmp/mysql.sock.  There are two easy ways to solve the problem.</p>
<p><span id="more-266"></span></p>
<p><strong>Solution 1: Create a symbolic link</strong></p>
<p>Open terminal and do the following:</p>
<p>sudo su<br />
mkdir /var/mysql<br />
ln -s /tmp/mysql.sock /var/mysql/mysql.sock</p>
<p>You just created a symbolic link in the place where PHP expects the socket file to be located so it should be happy.</p>
<p><strong>Solution 2: Edit php.ini</strong></p>
<p>If you don&#8217;t like the idea of creating a symbolic link, you can also simply alter your php.ini file to point PHP to the real location of mysql.sock.</p>
<p>Locate /etc/php.ini.  (If php.ini doesn&#8217;t exist on your system, copy /etc/php.ini.default to /etc/php.ini).  You will likely have to do this from the terminal unless you have Finder configured to show hidden files.  Open the file and update the setting mysql.default_socket so it looks like this:</p>
<p>mysql.default_socket = /tmp/mysql.sock</p>
<p>To commit the change you need to restart Apache.  You can do that in System Settings -&gt; Sharing, then  uncheck, then recheck Web Sharing.</p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2009/01/07/php-on-os-cant-connect-to-local-mysql-server-through-socket-varmysqlmysqlsock/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Working with dates in Flex AIR and SQLite</title>
		<link>http://verysimple.com/2008/09/09/working-with-dates-in-flex-air-and-sqlite/</link>
		<comments>http://verysimple.com/2008/09/09/working-with-dates-in-flex-air-and-sqlite/#comments</comments>
		<pubDate>Tue, 09 Sep 2008 21:38:49 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[AIR]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/?p=149</guid>
		<description><![CDATA[UPDATE 3/25/09: Paul Robertson from the AIR team stopped by and writes that declaring your SQLite column affinity (ie column type) as &#8220;DATE&#8221; will instruct AIR to handle all date conversions for you automatically.  The problems I experienced mainly surfaced in a DataGrid when using a DateField and I have not had a chance to [...]]]></description>
			<content:encoded><![CDATA[<p>UPDATE 3/25/09: Paul Robertson from the AIR team stopped by and writes that declaring your SQLite column affinity (ie column type) as &#8220;DATE&#8221; will instruct AIR to handle all date conversions for you automatically.  The problems I experienced mainly surfaced in a DataGrid when using a DateField and I have not had a chance to poke around with that yet.  Another approach is to extend DateField and override the &#8220;data&#8221; setter which is how the DataGrid supplies item editors with their value.  Then you can deal with casting issues manually, however that may be more of a hack.  The article below still has some good information that is still helpful for dealing with Dates in AIR/SQLite.</p>
<p>Working with SQLite and Flex/AIR Date values can be tricky and various caveats are not particularly well documented.  The confusion (for me) is that ActionScript is loaded with UTC functions, and SQLite will happily insert them into DATETIME columns.  Everything appears fine, however SQLite does not actually recognize this format as a Date and treats it as plain text.  You have no way to see this happened until you try to apply some date formatting functions and notice SQLite returning NULL.  SQLite is so lax about data integrity that you can insert anything into any column type and will never receive any warnings.  AIR, though, will attempt to cast values behind the scenes based on column types and so you will run into &#8216;Invalid Date&#8217; errors and weird glitches when attempting to update data.</p>
<p>The magic solution is the <a href="http://en.wikipedia.org/wiki/Julian_Day_Number">Julian Date Format</a> which both SQLite and AIR recognize as a date value.  This is somewhat surprising as ActionScript has no built-in support for outputting Julian dates.  If you&#8217;re like me, you may have already hacked up workarounds using int fields with timestamps, however your matching ActionScript class properties have to be hacked to match, and the hacking can trickle down throughout your code.  This also prevents you from using the SQLStatement.itemClass functionality, which is nice when using Cairngorm, DAOs, value objects, etc.</p>
<p><strong>To avoid the pain follow these rules when working with dates:</strong></p>
<p>1. If you want a strongly typed Date field in AIR, the relevant SQLite column must be defined as DATETIME.  The interesting thing about this is that DATETIME is not technically a <a href="http://www.sqlite.org/datatype3.html" target="_blank">recognized SQLite column type</a> and according to the SQLite docs it will be considered numeric.  But AIR is obviously looking at the column definition somewhere in the framework because it will refuse to automatically cast any value where the column type is not DATETIME.</p>
<p>2. Whenever inserting or updating DATETIME fields, you must store it in Julian format (or NULL).   SQLite will happily accept many common date formats.  However AIR will behave inconsistently.  Here is how to insert Julian dates in a variety of ways:</p>
<p><em>Inserting a Julian date manually via SQL:</em></p>
<p>To do this, simply have SQLite format your date value to Julian format using &#8216;%J&#8217;</p>
<pre>UPDATE my_table SET my_column = STRFTIME('%J','2008-01-02 03:04:05')</pre>
<p><em>Inserting a Julian date via AIR (with parameters):</em></p>
<p>Parameters are the best way to build SQL statements as you can use strongly typed Date variables and AIR will deal with the formatting for you.</p>
<pre>statement.text = "UPDATE my_table SET my_column = :my_value";
statement.parameters[":my_value"] = new Date(2008,0,2,3,4,5); // Jan 02, 2008 03:04:05</pre>
<p><em>Inserting a Julian date via AIR (without parameters):</em></p>
<p>If you are not using parameters, you have to pre-format the date into something that SQLite can parse.  This is surprisingly obnoxious and requires you to write a couple of helper functions. (Note &#8211; if you know of an easier way to do this, please post a comment.)</p>
<pre>public function lpad(original:Object, length:int, pad:String):String
{
var padded:String = original == null ? "" : original.toString();
while (padded.length &lt; length) padded = pad + padded;
return padded;
}

public function toSqlDate(dateVal:Date):String
{
return dateVal == null ? null : dateVal.fullYear
+ "-" + lpad(dateVal.month + 1,2,'0')  // month is zero-based
+ "-" + lpad(dateVal.date,2,'0')
+ " " + lpad(dateVal.hours,2,'0')
+ ":" + lpad(dateVal.minutes,2,'0')
+ ":" + lpad(dateVal.seconds,2,'0')
;
}

var myDate:Date = new Date(2008,0,2,3,4,5); // Jan 02, 2008 03:04:05
statement.text = "UPDATE my_table SET my_column = strftime('%J','" + toSqlDate(myDate) + "')";</pre>
<p><strong>Fudging data to work around AIRs validation</strong></p>
<p>If you absolutely refuse to change your schema (for example you insist on using timestamps, or you have to maintain compatibility with other clients) you can get AIR to play along during READ operations by altering your select statement like so:</p>
<pre>SELECT STRFTIME('%J',my_column) as my_column from my_table</pre>
<p>This does assume that the data is in a format that SQLite recognizes as a date.  If SQLite can&#8217;t parse the date value, then it will just return NULL.  For hilarity sake, you can also use <a href="http://www.verysimple.com/blog/2008/09/08/rediculous-date-formatting-in-sqlite/">this ridiculous date format </a>which surprisingly works with AIR.  A word of warning about this workaround is that, even though you will be able to read data, you may not be able to update data via SQLCommand parameters if your column types are DATETIME because AIR will complain about an invalid date (see errors below).  You will have either have to write your own SQL statements without parameters or else change your column types to int or varchar.</p>
<p><strong>Formatting a Julian date manually in SQL so you can read it:</strong></p>
<p>Julian values are great and all that, but it&#8217;s pretty much impossible to eyeball them when you&#8217;re working at the command line.  SQLite recognizes Julian formatting as a valid date, so you can use the STRFTIME function to format and output it any way you like.  Below is a simple example that is easier to read:</p>
<pre>SELECT STRFTIME('%Y-%m-%d %H:%M:%S',my_column) as my_column_formatted FROM my_table</pre>
<p><strong>Common errors that occur while working with dates:</strong></p>
<p><em>Invalid Date</em></p>
<p>You may see this in a DataGrid instead of the expected date value.  This is because you have a DATETIME column in SQLite, however the value is not in Julian format.  Even though SQLite may recognize it as a date value, AIR does not.  The solution is to clean your data so that all dates are Julian format, or alternatively change the column type to VARCHAR.</p>
<p><em>&#8216;Error #3115: SQL Error.&#8217;, details:&#8217;could not convert string value to date&#8217;</em></p>
<p>This error occurs when you try to update a record that has one or more DATETIME columns that do not have the date stored in Julian format.  The weird part is that even if you are not touching that specific column in your insert/update statement &#8211; AIR will still validate the Date and throw this error. The solution is to clean your data so that all dates are Julian format, or alternatively change the column type to VARCHAR.</p>
<p>If you have any tips or corrections please post a comment and I&#8217;ll incorporate it into the article.</p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2008/09/09/working-with-dates-in-flex-air-and-sqlite/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Ridiculous date formatting in SQLite</title>
		<link>http://verysimple.com/2008/09/08/rediculous-date-formatting-in-sqlite/</link>
		<comments>http://verysimple.com/2008/09/08/rediculous-date-formatting-in-sqlite/#comments</comments>
		<pubDate>Mon, 08 Sep 2008 22:15:38 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[SQLite]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/?p=171</guid>
		<description><![CDATA[The following code outputs a SQLite date into a standard date format with month abbreviations that, believe it or not, Flex/AIR will accept as a Date value (Though SQLite itself doesn&#8217;t recognize it as a valid DATETIME!). I created this atrocious code while trying to figure out the mysterious interaction between AIR and SQLite date [...]]]></description>
			<content:encoded><![CDATA[<p>The following code outputs a SQLite date into a standard date format with month abbreviations that, believe it or not, Flex/AIR will accept as a Date value (Though SQLite itself doesn&#8217;t recognize it as a valid DATETIME!).  I created this atrocious code while trying to figure out the <a href="http://www.verysimple.com/blog/2008/09/09/working-with-dates-in-flex-air-and-sqlite/">mysterious interaction between AIR and SQLite date values</a>.  Julian time format is what you should use, though, for AIR applications.  I decided to post this code up just for curiosity sake and future reference:</p>
<pre>
SELECT
   CASE WHEN (  strftime('%m',my_column)   = '01') THEN ('Jan') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '02') THEN ('Feb') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '03') THEN ('Mar') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '04') THEN ('Apr') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '05') THEN ('May') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '06') THEN ('Jun') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '07') THEN ('Jul') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '08') THEN ('Aug') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '09') THEN ('Sep') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '10') THEN ('Oct') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '11') THEN ('Nov') ELSE '' END
|| CASE WHEN (  strftime('%m',my_column)   = '12') THEN ('Dec') ELSE '' END
|| STRFTIME(' %d %H:%M:%S GMT-0600 %Y', my_column)
FROM my_table
</pre>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2008/09/08/rediculous-date-formatting-in-sqlite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Subtracting unsigned integers with MySQL</title>
		<link>http://verysimple.com/2007/12/07/subtracting-unsigned-integers-with-mysql/</link>
		<comments>http://verysimple.com/2007/12/07/subtracting-unsigned-integers-with-mysql/#comments</comments>
		<pubDate>Fri, 07 Dec 2007 05:01:57 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/2007/12/07/subtracting-unsigned-integers-with-mysql/</guid>
		<description><![CDATA[Unsigned integer values are used in a database when you only expect to contain positive values and no negative values (less than zero). If you know a certain field will never legitimately contain negative values, then this is actually the most efficient field type to select. There is a catch with unsigned ints however that [...]]]></description>
			<content:encoded><![CDATA[<p>Unsigned integer values are used in a database when you only expect to contain positive values and no negative values (less than zero).  If you know a certain field will never legitimately contain negative values, then this is actually the most efficient field type to select.</p>
<p>There is a catch with unsigned  ints however that can create problems for you if you&#8217;re not careful.  That is, when you subtract unsigned ints, you will <em>always </em>get a positive value back no matter what.  What does that mean?</p>
<p>Say you have a table for products with two unsigned fields: <strong>qty_in_stock</strong> and <strong>qty_sold</strong>.  Lets assume for whatever reason you oversold your inventory and qty_in_stock now equals  100, but qty_sold = 101.  So take the following statement:</p>
<pre>SELECT qty_in_stock - qty_sold as qty_remaining FROM products</pre>
<p>You would expect qty_remaining to be -1, right?  Wrong!  In fact MySQL returns <strong>18446744073709551615</strong> !</p>
<p>Why would this happen?  Well, because MySQL is built so that when you perform a math operation on two unsigned ints, it will always return an unsigned int.  And -1 is technically an out-of-bounds value for an unsigned field type.  Instead of complaining, MySQL returns the value that would have represented -1 if it were unsigned which is 18446744073709551615.</p>
<p>Mathematically, I suppose this is correct, however it doesn&#8217;t make any logical sense to me.  If anything, I think MySQL should throw an out-of-bounds error when this happens because the default behavior seems very unintuitive to me.  It is as though they are trying to say that one positive value subtracted from another can never result in a negative value.  Of course this is false, but that is how MySQL works.</p>
<p>There are two solutions to this.  The first is to simply use signed ints if you ever expect them to be used in a subtraction formula.  You waste some space, but it&#8217;s an easy fix.</p>
<p>The second solution is, if you are able to edit your SQL statement that have the subtraction, you can use the MySQL cast function.  The example from above could be converted to the following:</p>
<pre>SELECT cast(qty_in_stock - qty_sold as signed) as qty_remaining FROM products</pre>
<p>So there is a solution to this &#8220;problem&#8221; if you will.  You can read more about this subject on the MySQL site at <a href="http://dev.mysql.com/doc/refman/4.1/en/cast-functions.html" target="_blank">http://dev.mysql.com/doc/refman/4.1/en/cast-functions.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2007/12/07/subtracting-unsigned-integers-with-mysql/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Beyond auto-id: Advanced Sequential Numbering with MySQL</title>
		<link>http://verysimple.com/2007/06/09/insert-sequential-numbers-in-mysql/</link>
		<comments>http://verysimple.com/2007/06/09/insert-sequential-numbers-in-mysql/#comments</comments>
		<pubDate>Sun, 10 Jun 2007 02:16:55 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/2007/06/09/insert-sequential-numbers-in-mysql/</guid>
		<description><![CDATA[MySQL auto-id function provides the ability to automatically create a new id for each new record on insert. This works great for unique ids, but sometimes more logic is required. For a recent assignment we needed to populate a table that reflects seating in a stadium. The seating was typical of most venues consisting of [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL auto-id function provides the ability to automatically create a new id for each new record on insert.  This works great for unique ids, but sometimes more logic is required.</p>
<p>For a recent assignment we needed to populate a table that reflects seating in a stadium.  The seating was typical of most venues consisting of Aisles and Seats.  For example, A-1, A-2, A-3, B-1, B-2, B-3, and so on. When the table was initially populated, the seat_number field was all set at it&#8217;s default value of &#8217;1&#8242;.  So we needed sequential numbers for the seats, but the count had to start over with each new Aisle.  This could have been done easily in a scripting language, but what fun is that!  We wanted to accomplish the numbering in one regular SQL statement.</p>
<p>This problem would be easily solved using Oracle&#8217;s rownum functionwhere we can get a sequential id for each row within a resultset.  But, alas, MySQL doesn&#8217;t have a rownum function.  What we did find, however, is a wonderful hack on <a href="http://markmal.blogspot.com/2006/04/oracle-like-rownum-in-mysql.html" target="_blank">Mark Malakonov&#8217;s blog</a> that duplicates this functionality for MySQL.</p>
<p>The final query, which only updates Aisle &#8216;A&#8217; is here:</p>
<pre>update venue_seat set seat_number =
(select @rownum:=@rownum+1 rownum FROM (SELECT @rownum:=0) r)
where aisle = 'A'
</pre>
<p>These fields obviously relate to a specific schema, however the @rownum trick can be used to generate sequential numbers for your tables as well. If you need to update or populate a table with sequential numbers but need some additional logic, this is a handy trick to have in your toolbox.</p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2007/06/09/insert-sequential-numbers-in-mysql/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>MySQL Error Number 1005 Can&#039;t create table &#039;.\mydb\#sql-328_45.frm&#039; (errno: 150)</title>
		<link>http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/</link>
		<comments>http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/#comments</comments>
		<pubDate>Mon, 23 Oct 2006 04:06:36 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/?p=58</guid>
		<description><![CDATA[MySQL Error Number 1005 Can&#8217;t create table &#8216;.\mydb\#sql-328_45.frm&#8217; (errno: 150) If you get this error while trying to create a foreign key, it can be pretty frustrating. The error about not being able to create a .frm file seems like it would be some kind of OS file permission error or something but this is [...]]]></description>
			<content:encoded><![CDATA[<p>MySQL Error Number 1005<br />
Can&#8217;t create table &#8216;.\mydb\#sql-328_45.frm&#8217; (errno: 150)</p>
<p>If you get this error while trying to create a foreign key, it can be pretty frustrating.  The error about not being able to create a .frm file seems like it would be some kind of OS file permission error or something but this is not the case.  This error has been reported as a bug on the MySQL developer list for ages, but it is actually just a misleading error message.</p>
<p>In every case this is due to something about the relationship that MySQL doesn&#8217;t like.  Unfortunately it doesn&#8217;t specify what the exact issue is.  Here is a running list of causes that people have reported for the dreaded errno 150.  I&#8217;ve tried to put them in order based on the frequency that I hear about  a particular cause.</p>
<p><em>You may want to start by running the MySQL command &#8220;SHOW INNODB STATUS&#8221; immediately after receiving the error.  This command displays log info and error details. (Thanks Jonathan for the tip)</em></p>
<p><em>Note: If your script runs fine on one server, but gives an error when you try to run it on a different server, then there is a good chance that #6 is the problem.  Different versions of MySQL have different default charset setting.<br />
</em></p>
<p><strong>Known Causes:</strong></p>
<ol>
<li>The two key fields type and/or size doesn&#8217;t match exactly.  For example, if one is INT(10) the key field needs to be INT(10) as well and not INT(11) or TINYINT.  You may want to confirm the field size using SHOW CREATE TABLE because Query Browser will sometimes visually show just INTEGER for both INT(10) and INT(11). You should also check that one is not SIGNED and the other is UNSIGNED.  They both need to be exactly the same.  (<a href="http://www.verysimple.com/blog/?p=57">More about signed vs unsigned here</a>).</li>
<li>One of the key field that you are trying to reference does not have an index and/or is not a primary key. If one of the fields in the relationship is not a primary key, you must create an index for that field. (thanks to Venkatesh and Erichero and Terminally Incoherent for this tip)</li>
<li>The foreign key name is a duplicate of an already existing key. Check that the name of your foreign key is unique within your database.  Just add a few random characters to the end of your key name to test for this. (Thanks to Niels for this tip)</li>
<li>One or both of your tables is a MyISAM table.  In order to use foreign keys, the tables must both be InnoDB.  (Actually, if both tables are MyISAM then you won&#8217;t get an error message &#8211; it just won&#8217;t create the key.)  In Query Browser, you can specify the table type.</li>
<li>You have specified a cascade ON DELETE SET NULL, but the relevant key field is set to NOT NULL.  You can fix this by either changing your cascade or setting the field to allow NULL values. (Thanks to Sammy and J Jammin)</li>
<li>Make sure that the Charset and Collate options are the same both at the table level as well as individual field level for the key columns.  (Thanks to FRR for this tip)</li>
<li>You have a default value (ie default=0) on your foreign key column (Thanks to Omar for the tip)</li>
<li>One of the fields in the relationship is part of a combination (composite) key and does not have it&#8217;s own individual index. Even though the field has an index as part of the composite key, you must create a separate index for only that key field in order to use it in a constraint. (Thanks to Alex for this tip)</li>
<li>You have a syntax error in your ALTER statement or you have mistyped one of the field names in the relationship (Thanks to  Christian &amp; Mateo for the tip)</li>
<li>The name of your foreign key exceeds the max length of 64 chars.  (Thanks to Nyleta for the tip)</li>
</ol>
<p>The MySQL documentation includes a <a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-foreign-key-constraints.html" target="_blank">page explaining requirements for foreign keys</a>.  Though they don&#8217;t specifically indicate it, these are all potential causes of errno 150.  If you still haven&#8217;t solved your problem you may want to check there for deeper technical explainations.If you run into this error and find that it&#8217;s caused by something else, please leave a comment and I&#8217;ll add it to the list.</p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2006/10/22/mysql-error-number-1005-cant-create-table-mydbsql-328_45frm-errno-150/feed/</wfw:commentRss>
		<slash:comments>128</slash:comments>
		</item>
		<item>
		<title>MySQL Data Type Optimization Tips</title>
		<link>http://verysimple.com/2006/10/22/mysql-data-type-optimization-tips/</link>
		<comments>http://verysimple.com/2006/10/22/mysql-data-type-optimization-tips/#comments</comments>
		<pubDate>Mon, 23 Oct 2006 00:27:27 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/?p=57</guid>
		<description><![CDATA[A lot of people might classify this as a &#8220;newbie&#8221; piece. But, I would say that I&#8217;ve seen inefficient data usage plenty of times due to just laziness. Some people might even say &#8220;premature optimization is the root of all evil&#8221; and just make field sizes way bigger than they need. I like to try [...]]]></description>
			<content:encoded><![CDATA[<p>A lot of people might classify this as a &#8220;newbie&#8221; piece.  But, I would say that I&#8217;ve seen inefficient data usage plenty of times due to just laziness.   Some people might even say &#8220;premature optimization is the root of all evil&#8221; and just make field sizes way bigger than they need.  I like to try to keep my DB lean-and-mean when possible, though.  Everyone, myself included, gets lazy once in a while when cranking out some prototype code.</p>
<p>These tips are not necessarily MySQL specific, but I&#8217;m using MySQL syntax as an example for the sake of simplicity.</p>
<p><strong>SIGNED vs UNSIGNED</strong></p>
<p>This is probably the easiest habit to practice because you have nothing to lose and everything to gain by using SIGNED /UNSIGNED  data types in the right place. There&#8217;s a simple question you can ask &#8211; will this field ever contain a negative value?   If the answer is no, then you want an UNSIGNED data type.</p>
<p>A common mistake that I see is a primary key that is an auto-increment INT starting at zero, yet the type is SIGNED.  An UNSIGNED INT can go from 0 to 4294967295 (aprox 4 billion).  A SIGNED INT , on the other hand, starts at -2147483648 and goes to 2147483648 (aprox 2 billion).  If you use an auto-increment starting at 0, you&#8217;ll never touch any of those negative numbers and your Id column will top out at around 2 billion.</p>
<p><strong>Use a Smaller ID Data Type for Small Tables</strong></p>
<p>You don&#8217;t usually know how many records your application will eventually store.  You don&#8217;t want to use too small a data type in the event that your app gets popular.  You might tend to use INT for your primary key column just out of habit.</p>
<p>In some situations, though, you do have a pretty good idea of how many records you&#8217;ll have and so you don&#8217;t need to use an INT as the primary key.  For tables that contain things like permissions, system settings, account types, etc you may know that you will never need a huge number of records.  You may not even create a user interface to access these tables or insert new records.</p>
<p>In cases like this, I find an UNSIGNED TINYINT is perfect.  This will hold values from 0 to 255.  Sometimes 255 is more than enough, but still gives you room to grow.  You don&#8217;t want to do this if you expect to get close to this limit of course. If the data is strictly internal and there&#8217;s no user interface, the developer is usually in control of these records.</p>
<p>A lot of people use UNSIGNED INT as their primary key which as I mentioned earlier goes up to over 4 billion records.  That is a lot of records!  An UNSIGNED MEDIUMINT goes up to 16 million records which is still more than most tables need.  An UNSIGNED SMALLINT goes up to 65 thousand records.  You don&#8217;t want to run out of space, but you can try to optimize a bit for the best performance.  Keep in mind that your primary key is the field that will be theoretically used the most for record lookups, so the more efficient you can make it the faster your app will run.</p>
<p><a href="http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html">Read more about numerical datatypes on the MySQL site&#8230;</a></p>
<p><strong>Know the Difference Between CHAR and VARCHAR</strong></p>
<p>CHAR and VARCHAR both hold string/text data.  However they work a little differently because CHAR is like a fixed-size array that is always the same size, where as VARCHAR will expand and contract to fit the data.</p>
<p>The CHAR type is useful if you have a good idea of the size that the field will be.  A product code that is always 10 digits, for example, is a great candidate for a CHAR data type.  The negative side of the CHAR type is that it will use up the disk space whether or not you need it.  For example, if you have a CHAR(25) but your record only uses up 5 characters, MySQL will still use up all 25 on disk.</p>
<p>The VARCHAR is convenient because you can set it to 25, but if you only store 5 characters, the VARCHAR will only use the space it needs.  Two tradeoffs for this convenience are performance and fragmentation.  In particular, when you update a VARCHAR field, you might outgrow the space that was originally allocated.  Your data becomes fragmented so that one record may be spread out across the DB file instead of in one nice, continuous chunk.   So as time goes by, your access to the VARCHAR data will require more processing power.</p>
<p>MySQL provides a solution in the way of the OPTIMIZE TABLE statement.  This basically will de-fragment your table VARCHAR fields.  If you are using VARCHARS and doing a lot of updating, you should make sure to optimize the tables periodically.  This is something that can be automated through cron or Scheduled Tasks so that you don&#8217;t forget.</p>
<p>In case you think it&#8217;s a simple choice, keep in mind that table size and performance are closely related.  So, it follows that the VARCHAR would deliver performance benefits due to it being the smallest possible size.  That would offset the performance benefit that the consistency of CHAR delivers.  My rule of thumb is to use CHAR if you have a pretty good idea of the field size.</p>
<p>More reading is available on the MySQL site, however I find the user comments on the end of <a href="http://dev.mysql.com/doc/refman/5.0/en/char.html">this page</a> more interesting than the official documentation.</p>
<p><strong>Don&#8217;t mix &#8220;SELECT * FROM&#8221; with TEXT/BLOB fields</strong></p>
<p>TEXT and BLOB fields are extremently useful for storing large datatypes.  File uploads, XML data, long text content, etc usually require one of these types of fields. Unfortunately, these fields can make a table grow large quickly.  Storing binary file data for example can make a DB table enormous.</p>
<p>Depending on your application, this may just be the best way to store this type of data.  However, if you don&#8217;t need this data on every query, then don&#8217;t select it.  Here&#8217;s an example:</p>
<p><em>select * from file_upload where fu_owner_id = &#8217;1&#8242;</em></p>
<p>What we&#8217;re doing here is grabbing the full row contents for the file uploads, though we may not need all of that data. You can imagine that this query might select all of the files that have been uploaded by a specific user for us to show in a datagrid, dropdown list or whatever.  The issue here is that you rarely need to have the *contents* of the files when you are displaying them in a list.  If possible, this might be better:</p>
<p><em>select fu_id, fu_name from file_upload where fu_owner_id = &#8217;1&#8242;</em></p>
<p>In this case we have the primary key (fu_id) and the file name (fu_name).  We can show this in the list  Now, if the user wants to download or see the contents of the file, you can grab it using the primary key:</p>
<p><em>select fu_name, fu_data from file_upload where fu_id = &#8217;55&#8242;</em></p>
<p>An alternative approach is to use a dedicated table with only a primary key and the BLOB/TEXT field.  Any other tables that need to store large values can simply have a reference to that table&#8217;s primary key instead.  If you only do lookups from the dedicated table by it&#8217;s primary key, then you&#8217;ll avoid any full table scans.</p>
<p><strong>Read The Fine Manual</strong></p>
<p>The MySQL site has plenty of information describing the various data types.  The little bit of time and effort that you put into tuning your database will pay off as your application grows.</p>
<p>More reading on MySQL 5 data types can be found here: <a title="http://dev.mysql.com/doc/refman/5.0/en/data-types.html" href="http://dev.mysql.com/doc/refman/5.0/en/data-types.html">http://dev.mysql.com/doc/refman/5.0/en/data-types.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2006/10/22/mysql-data-type-optimization-tips/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Transfer SQL Server Database Preserving Keys and Identities</title>
		<link>http://verysimple.com/2006/03/30/transfer-sql-server-database-preserving-keys-and-identities/</link>
		<comments>http://verysimple.com/2006/03/30/transfer-sql-server-database-preserving-keys-and-identities/#comments</comments>
		<pubDate>Thu, 30 Mar 2006 10:00:00 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[MS SQL Server]]></category>

		<guid isPermaLink="false">http://www.verysimple.com/blog/?p=44</guid>
		<description><![CDATA[If you try to transfer a database from one SQL Server to another using the Enterprise Manager data transfer wizard, you may notice that your primary key and identity properties do not transfer correctly. To transfer these, you have to use the &#8220;Transfer Objects&#8221; and change a few of the defaults. If you just accept [...]]]></description>
			<content:encoded><![CDATA[<p>If you try to transfer a database from one SQL Server to another using the Enterprise Manager data transfer wizard, you may notice that your primary key and identity properties do not transfer correctly.</p>
<p>To transfer these, you have to use the &#8220;Transfer Objects&#8221; and change a few of the defaults.  If you just accept all the defaults, you won&#8217;t get any of your keys on the copied database.</p>
<p>1. Right click on the source database and from All Tasks click &#8220;Export&#8221;</p>
<p>2. Choose the source DB and click next</p>
<p>3. Choose the destination DB and click next</p>
<p>NEXT STEPS ARE IMPORTANT SO KEYS AND IDENTITIES IMPORT CORRECTLY &#8211; PAY ATTENTION!!</p>
<p>4. Choose the option to &#8220;Copy Objects and Data between SQL Server Databases&#8221;</p>
<p>5. Check the box that says &#8220;Include Extended Properties&#8221; (I haven&#8217;t confirmed, but I think this is what copies over the Identity property)</p>
<p>6. If you don&#8217;t want all the tables, de-select &#8220;Copy all Objects&#8221; and click the &#8220;Select Objects&#8230;&#8221; button to choose the tables to copy.</p>
<p>7. De-select &#8220;Use Default Options&#8221; and click the &#8220;Options&#8230;&#8221; button.  On the options screen, de-select &#8220;Copy database users and database roles&#8221; unless you have admin access to both servers and you want the same usernames to be used on both servers.  If you get errors that the user does not exist, or you get duplicate tables with different username (schemas) then this is the cause.</p>
<p>8. Click next and run immediately or schedule.  The data migration wizard should run.  Check your new tables to make sure they have keys and identities correct.</p>
<p>Another thing to pay attention is that you can have duplicate tables like so:</p>
<p>[dbo].[Table1]<br />
[username].[Table1]</p>
<p>This can cause all kinds of grief because they are treated as totally different tables and you will see only the one for which you are logged in.  So, if you login to to SQL server as sa, you&#8217;ll see both tables.  Your web app might only see the user-specific one.  Pay attention to step 7 above to prevent this situation.</p>
]]></content:encoded>
			<wfw:commentRss>http://verysimple.com/2006/03/30/transfer-sql-server-database-preserving-keys-and-identities/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
