<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-13517334</id><updated>2011-12-15T03:02:42.483Z</updated><category term='memcached'/><category term='mysql'/><category term='Oracle'/><category term='web performance'/><title type='text'>gilfster</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>92</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-13517334.post-8107466734616214893</id><published>2009-04-14T14:45:00.004Z</published><updated>2009-04-15T09:24:53.286Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><title type='text'>Generating "Random" Data using rand() and sub selects</title><content type='html'>I'm developing a demonstration site for new system we are about to unleash on the world, so far it's going great but one of the worst things about demo sites is the lack of real world data at hand. I don't want to give too much away but the site is vehicle sales based and I need to generate a bunch of data. The problem I needed to solve was that the table with the cars in didn't have associated dealer data and the pages looked very bare when there wasn't any as much of the data comes from the dealers table. &lt;br /&gt;&lt;br /&gt;I didn't fancy going in to the table and amending 165 cars by hand, but I also didn't want to run the update in blocks as I wanted an a pretty even spread of the different cars between the 12 dealers. Take for example this data set... &lt;br /&gt;&lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;mysql&gt; select id, Make, dealer from cars_cars limit 5;&lt;br /&gt;&lt;br /&gt;+----+------------+-----------+&lt;br /&gt;| id | Make       | dealer    |&lt;br /&gt;+----+------------+-----------+&lt;br /&gt;|  1 | Land Rover | Aldershot |&lt;br /&gt;|  2 | Land Rover |           |&lt;br /&gt;|  3 | Land Rover |           |&lt;br /&gt;|  4 | Land Rover |           |&lt;br /&gt;|  5 | Land Rover |           |&lt;br /&gt;+----+------------+-----------+&lt;br /&gt;5 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Only one of the vehicles has a dealer attached. What I want is to populate that dealer column with a real dealer. &lt;br /&gt;&lt;br /&gt;I always run updates in select mode first, to see what the final out put is like. First I want a way to get a random dealer, we can use rand() in the order by to generate a random number which MySQL will sort on. &lt;br /&gt;&lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;mysql&gt; select name from cars_dealers &lt;br /&gt;       order by rand() limit 1;&lt;br /&gt;+------------+&lt;br /&gt;| name       |&lt;br /&gt;+------------+&lt;br /&gt;| Birmingham |&lt;br /&gt;+------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select name from cars_dealers &lt;br /&gt;       order by rand() limit 1;&lt;br /&gt;+--------+&lt;br /&gt;| name   |&lt;br /&gt;+--------+&lt;br /&gt;| Oldham |&lt;br /&gt;+--------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now I can include that in my original select like so...&lt;br /&gt;&lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;mysql&gt; select id, Make, &lt;br /&gt;             (select name from cars_dealers &lt;br /&gt;                     order by rand() limit 1) as dealer &lt;br /&gt;              from cars_cars limit 5;&lt;br /&gt;+----+------------+-------------+&lt;br /&gt;| id | Make       | dealer      |&lt;br /&gt;+----+------------+-------------+&lt;br /&gt;|  1 | Land Rover | Oxford      |&lt;br /&gt;|  2 | Land Rover | Aldershot   |&lt;br /&gt;|  3 | Land Rover | Coventry    |&lt;br /&gt;|  4 | Land Rover | Southampton |&lt;br /&gt;|  5 | Land Rover | Birmingham  |&lt;br /&gt;+----+------------+-------------+&lt;br /&gt;5 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Great, so I now have a random dealer against each vehicle, all I need now is to turn that into an update and we are good to go.&lt;br /&gt;&lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;mysql&gt; update cars_cars &lt;br /&gt;       set dealer = &lt;br /&gt;           (select name from cars_dealers &lt;br /&gt;                   order by rand() limit 1)&lt;br /&gt;       where id &gt; 0;&lt;br /&gt;&lt;br /&gt;Query OK, 163 rows affected (0.01 sec)&lt;br /&gt;Rows matched: 163  Changed: 163  Warnings: 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I now have "random" data in my table. I put random in quotes because it is random within a set range of values not totally random as in totally unpredictable. Just to prove it really did work.&lt;br /&gt;&lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;mysql&gt; select id, Make, dealer from cars_cars limit 5;&lt;br /&gt;+----+------------+---------------+&lt;br /&gt;| id | Make       | dealer        |&lt;br /&gt;+----+------------+---------------+&lt;br /&gt;|  1 | Land Rover | Aldershot     |&lt;br /&gt;|  2 | Land Rover | Basingstoke   |&lt;br /&gt;|  3 | Land Rover | Wolverhampton |&lt;br /&gt;|  4 | Land Rover | Aldershot     |&lt;br /&gt;|  5 | Land Rover | Wolverhampton |&lt;br /&gt;+----+------------+---------------+&lt;br /&gt;5 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;* I used where id &gt; 0 because as mentioned in my previous post I have safe update mode turned on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-8107466734616214893?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/8107466734616214893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=8107466734616214893' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/8107466734616214893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/8107466734616214893'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2009/04/generating-random-data-using-rand-and.html' title='Generating &quot;Random&quot; Data using rand() and sub selects'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-2834405501969115577</id><published>2009-04-09T14:29:00.003Z</published><updated>2009-04-09T14:44:00.037Z</updated><title type='text'>I am a Dummy</title><content type='html'>Way back when I started this blog just under 4 years ago I wrote a post called 'An Oracle Developers Journey', in the early days the blog focused on the transition from Oracle to MySQL. The irony was that after a year or so professionally I move back the other way and for the last 3 years or so it's been all Oracle for me. &lt;br /&gt;&lt;br /&gt;We all make mistakes, I know I have made some massive ones in the past, some were saved by a decent back up others were not so easy to recover from. It's been a while since I made anything like a big mistake (certainly not one that was noticed ;), once bitten twice shy tends to make you think about the consequences a little more. &lt;br /&gt;&lt;br /&gt;But having now switched back to MySQL again I find myself really worried I'm going to make a mistake, in Oracle it's UPDATE/INSERT or more worryingly DELETE and then a COMMIT, but in MySQL (at least the way we are running it) there is no commit stage. I'm currently working on development systems but I just know that one day I'm going to delete or update something I really don't want to. &lt;br /&gt;&lt;br /&gt;Thankfully MySQL is clever enough to make up for my itchy delete finger and includes the --safe-updates startup option. But I love the alias which is --i-am-a-dummy. I'm man enough to admit to being a dummy, well at least prone to doing something dum from time to time and that's why the first thing I did when I switched back to MySQL was to include --i-am-a-dummy in my startup alias. &lt;br /&gt;&lt;br /&gt;So hands up who else is a dummy?&lt;br /&gt;&lt;br /&gt;p.s. if you don't know --safe-updates sets the following session system variables.&lt;br /&gt;&lt;br /&gt;SET sql_safe_updates=1, &lt;br /&gt;sql_select_limit=1000, &lt;br /&gt;sql_max_join_size=1000000;&lt;br /&gt;&lt;br /&gt;sql_safe_updates is the key as it stops you running an update or delete without some sort of where clause.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-2834405501969115577?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/2834405501969115577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=2834405501969115577' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/2834405501969115577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/2834405501969115577'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2009/04/i-am-dummy.html' title='I am a Dummy'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-2893313790403323271</id><published>2009-03-26T10:17:00.003Z</published><updated>2009-03-26T10:31:14.998Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='memcached'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='web performance'/><title type='text'>Adventures in Web Performance</title><content type='html'>I mentioned in my previous post that recently I have been working with web performance. Often when working with clients they want fast performing web sites but then proceed to give you all manner of other requirements which slow the site down to a crawl. Convincing a client to give you the time to look at performance isn't easy, while the gains in speed are there for all to see attributing some monetary value to that is close to impossible. In the longer term you might see an up turn in the traffic levels or a higher percentage of people taking a longer user journey on your site but whether that was a result of higher performance is very difficult to prove. &lt;br /&gt;&lt;br /&gt;Thankfully one of our larger clients could see the benefit of having a dedicated resource looking at performance issues, all be it as a result of such poor performance that the sites became difficult to use during peek times. When a client keeps throwing stuff at you it's easy to take your eye off the performance issue and one thing that became clear was that while the tendency was to blame the database many of the things we looked at were nothing to do with that area. &lt;br /&gt;&lt;br /&gt;Over the next few posts I'll discuss some of the things we looked at, how we did that and how we radically improved performance on some of our sites with some minimal changes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-2893313790403323271?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/2893313790403323271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=2893313790403323271' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/2893313790403323271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/2893313790403323271'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2009/03/adventures-in-web-performance.html' title='Adventures in Web Performance'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-1794521304648448972</id><published>2009-03-26T10:10:00.003Z</published><updated>2009-03-26T10:16:50.486Z</updated><title type='text'>Such a long time....</title><content type='html'>Wow, is it really that long since I updated this thing. I can't believe that it's been close to 3 years since I updated it regularly, but I suppose it is as I have been in my current job for that long and it was a transition from MySQL back to Oracle (and a lot more work) that meant I stopped posting in the first place. &lt;br /&gt;&lt;br /&gt;The good news is I'm moving back to working with MySQL after 3 years away and that should give me some more opportunities to update the blog. While there have been some highlights over the 3 years much of the work I have been doing has been maintenance and the normal daily grind of work so it didn't offer that much that was interesting. Of late I have been doing some really cool stuff with web performance but I've been out of the blogging for so long I never really thought about sharing it. &lt;br /&gt;&lt;br /&gt;Of course any regular readers will be long gone but the blog still ranks pretty high in Google so maybe some folks will stop by.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-1794521304648448972?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/1794521304648448972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=1794521304648448972' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/1794521304648448972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/1794521304648448972'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2009/03/wow-is-it-really-that-long-since-i.html' title='Such a long time....'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-9215622061872731074</id><published>2007-06-22T09:30:00.000Z</published><updated>2007-06-22T09:55:06.104Z</updated><title type='text'>MySQL on a PS3</title><content type='html'>I work in IT for 2 reasons, firstly it pays well but secondly and most importantly it's fun. When I look back on jobs I had before I started working in IT, while it was never a problem getting up in the morning and the social aspects were great I would never have said that the job it self was fun.&lt;br /&gt;&lt;br /&gt;It's been sometime since I last updated the blog, 6 moths or so and almost a year since I did on anything like a regular basis, the main reason as I have mentioned in the past is that if you have nothing to say then why bother saying it. Therefore I doubt anybody is listening any longer, but I suppose that's not really an issue.&lt;br /&gt;&lt;br /&gt;I have been prompted to write because I have been doing some work on a site in MySQL, in the day job I use Oracle (but do some admin on MySQL sites from time to time) so I no longer have the experiences to blog about. But I recently needed to upgrade a family members web site which required some MySQL work. As it happens this coincided with a recent hardware upgrade, I used to have an X-Box 360 but it recently decided to die on me so I took the plunge to get a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Playstation&lt;/span&gt; 3. As games consoles go it's pretty decent and with the addition of a Blue-Ray drive it means I can take full advantage of my new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;HD&lt;/span&gt; TV.&lt;br /&gt;&lt;br /&gt;Getting back to the point, Sony allow you to format the PS3 hard drive in such a way that it can have two operating systems, the standard console one and also Linux. The install process looked easy and given that Sony fully supports this I thought I would give it a go. The PS3 allows the connection of a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;USB&lt;/span&gt; Keyboard and mouse so it's easy enough to get going. The install was painless enough (if a little long winded) but once it was done I now had a PS3 running Linux, of course one of the first things I did was have a go at running MySQL which of course runs like a dream.&lt;br /&gt;&lt;br /&gt;So now my development machine is a Sony PS3 :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-9215622061872731074?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/9215622061872731074/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=9215622061872731074' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/9215622061872731074'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/9215622061872731074'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2007/06/mysql-on-ps3.html' title='MySQL on a PS3'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-116661769991462728</id><published>2006-12-20T12:17:00.000Z</published><updated>2006-12-20T12:28:20.003Z</updated><title type='text'>Mysqldevelopment.com emails are no more.</title><content type='html'>When I transferred the content of mysqldevelopment.com over to the MySQL Forge site I always intended to continue updating this blog. Unfortunately due to work commitments I simply haven't had the time and because I haven't been working with MySQL so much I also haven't had the quality of content I once had. &lt;br /&gt;&lt;br /&gt;Rather unsurprisingly then I haven't been receiving much in the way of email to my email address andrew_gilfrin@mysqldevelopment.com. I have however been getting plenty of spam so I have decided to drop that email address, therefore if you wish to contact me you can do so at my hotmail address (andrew_gilfrin at homtail.com).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-116661769991462728?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/116661769991462728/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=116661769991462728' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/116661769991462728'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/116661769991462728'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/12/mysqldevelopmentcom-emails-are-no-more.html' title='Mysqldevelopment.com emails are no more.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-115323453161136109</id><published>2006-07-18T14:45:00.000Z</published><updated>2006-07-18T14:56:59.673Z</updated><title type='text'>Spotlight on MySQL</title><content type='html'>One of my "part time" roles is a sysop on the Quest MySQL Pipelines, as I have mentioned on here before we don't get many posts unfortunately and I can only assume that's because MySQL have such great forums of their own. &lt;br /&gt;&lt;br /&gt;Anyway, Quest produce a product called Spotlight on MySQL which is a &lt;a href="http://www.quest.com/spotlight_on_mysql/visual_overview.html"&gt;rather cool looking&lt;/a&gt; monitoring tool for MySQL. Personally I haven't had the chance to use it but the development team are currently looking for feedback on Spotlight on MySQL, with particular interest in if there is need for replication support.&lt;br /&gt;&lt;br /&gt;So if you have anything to add pop over to the forum and let the guys know in the Spotlight on MySQL section. &lt;br /&gt;&lt;br /&gt;http://pipetalk.quest-pipelines.com/default.asp?boardid=mysql&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-115323453161136109?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/115323453161136109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=115323453161136109' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/115323453161136109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/115323453161136109'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/07/spotlight-on-mysql.html' title='Spotlight on MySQL'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-115272308787995502</id><published>2006-07-12T16:11:00.000Z</published><updated>2006-07-12T16:52:18.436Z</updated><title type='text'>Regular Expressions in Oracle 10g - Part 1</title><content type='html'>Before my current role I generally worked in a windows environment, I would occasionally copy a file or log on to a Unix box to does something only when absolutely necessary. But at my last job and this current one I have had to spend most of my time connected to a Unix server, for as long as I could I'd edit in Windows and copy across to do what I needed but it soon became apparent that I'd need to get with the times ;) and take the plunge into Unix. &lt;br /&gt;&lt;br /&gt;I have found Unix to be really powerful and it didn't take anywhere near as long to get used to vi as I feared. One of the things I have most useful is regular expression, now I know that they are available in Windows in various places but in all my time with computers I had only a minimal amount of exposure to them. &lt;br /&gt;&lt;br /&gt;This then leads on to today's blog, In Oracle 10g a number of new functions were introduced that allow you to search and update using regular expressions. Over the next few days I'll be looking at what can be done but lets start with some simple examples. Let's take the following data set.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select * from reg_test;&lt;br /&gt;&lt;br /&gt;VAL_1&lt;br /&gt;------------------------------&lt;br /&gt;My name is Andrew&lt;br /&gt;My name is Dave&lt;br /&gt;My name is dave&lt;br /&gt;His name is dave&lt;br /&gt;His name is dave.&lt;br /&gt;He dave me andrew&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Before 10g we had to use like to search on sections of a column, this wasn't necessarily a problem but often involved using other functions to format the data in a way that we could search on. For example lets say we wanted to get a count of all of the records with Dave at the end, including those which were upper or lower case. Using like we would do something like this.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select count(*) from reg_test &lt;br /&gt;     where upper(val_1) like ('%DAVE');&lt;br /&gt;&lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;         3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's fine but it requires us to covert the whole of the val_1 to upper case so we can pick out the required fields. Also we have a count of 3 when realistically speaking we have 4, one of the rows has a full stop. We could to this..&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select count(*) from reg_test &lt;br /&gt;     where upper(val_1) like ('%DAVE%');&lt;br /&gt;&lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;         5&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now we are getting 5, because we have added the second %. To get round this in 10g we can now use REGEXP_LIKE, this allows us to use regular expressions as the comparison. &lt;br /&gt;&lt;br /&gt;I'll assume some knowledge of regular expressions (given you possibly know more about them than I do). &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select count(*) from reg_test &lt;br /&gt;     where regexp_like(val_1,'[Dd]ave\.*$');&lt;br /&gt;&lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;         4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This time we get the right result.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-115272308787995502?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/115272308787995502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=115272308787995502' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/115272308787995502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/115272308787995502'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/07/regular-expressions-in-oracle-10g-part.html' title='Regular Expressions in Oracle 10g - Part 1'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-115254766082901343</id><published>2006-07-10T15:56:00.000Z</published><updated>2006-07-10T16:08:10.393Z</updated><title type='text'>Adventures in PHP and Oracle</title><content type='html'>Recently we have been asked to develop some of our future sites in PHP. Traditionally we have worked in an in house language which fits in nicely with HTML but there is pressure from our clients to use something a little more "available" so that they can customise their sites themselves. &lt;br /&gt;&lt;br /&gt;The in house language connects to Oracle and we have a large library of Oracle Packages designed to get our information from the database in a structured way. One thing we do a lot is return data in collections rather than via ref cursors. The problem is that the current version of the Oracle Call Interface doesn't support returning arrays (collections) which have been defined within the header of a package. &lt;br /&gt;&lt;br /&gt;This means either rewriting some 500 packages/procedures or adding another layer of complexity to convert the returns into a data type PHP can handle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-115254766082901343?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/115254766082901343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=115254766082901343' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/115254766082901343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/115254766082901343'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/07/adventures-in-php-and-oracle.html' title='Adventures in PHP and Oracle'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114876205884683213</id><published>2006-05-27T20:32:00.000Z</published><updated>2006-05-27T20:34:18.873Z</updated><title type='text'>MySQLDevelopment.com</title><content type='html'>MySQLDevelopment.com is no more, All requests to the site will now be served from http://forge.mysql.com/wiki/Category:MySQLDevelopment.&lt;br /&gt;&lt;br /&gt;Thanks for all those who visited the site over the last year.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114876205884683213?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114876205884683213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114876205884683213' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114876205884683213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114876205884683213'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/05/mysqldevelopmentcom.html' title='MySQLDevelopment.com'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114743957250295685</id><published>2006-05-12T11:23:00.000Z</published><updated>2006-05-12T13:13:22.976Z</updated><title type='text'>MySQLDevelopment.com Update</title><content type='html'>I recently I announced that MySQLDevelopment was going to close, at the time I wasn't sure what would be happening to the content but I hoped that it would be able to live on in some form. &lt;br /&gt;&lt;br /&gt;I had a number of requests and suggestions with regard to the site and I felt the best option was to hand it over to MySQL for inclusion in the new MySQL Forge Wiki. My timing was a little off as the site was due to close during the MySQL conference but with that now out of the way the content of the site has been transfered and is available now at..&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forge.mysql.com/wiki/Category:MySQLDevelopment"&gt;http://forge.mysql.com/wiki/Category:MySQLDevelopment&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;I will be passing over the domain name to MySQL also but that may take some time to be up and running so MySQLDevelopment.com will still be available in the mean time.&lt;br /&gt;&lt;br /&gt;Now it's finally happening it's a little sad for me but this way I know the content can continue to grow and members of the community can contribute in real time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114743957250295685?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114743957250295685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114743957250295685' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114743957250295685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114743957250295685'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/05/mysqldevelopmentcom-update.html' title='MySQLDevelopment.com Update'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114623285026286169</id><published>2006-04-28T13:49:00.000Z</published><updated>2006-04-28T14:00:50.643Z</updated><title type='text'>MySQL Stored Procedure Programming (The Book) - 3</title><content type='html'>I have mentioned a couple of times about the upcoming release of MySQL Stored Procedure Programming by Guy Harrison and Steven Feuerstein. It was scheduled for release in March but the release date slipped a couple of times, I pre-ordered and the good news is that the book arrived this morning, so it's out now (in the UK at least). &lt;br /&gt;&lt;br /&gt;It weighs in at 636 pages so while it's not the door stopper that's often related to computer books there is a lot of information in there especially given the relatively recent addition of stored procedures to MySQL. Jay Pipes and Michael Kruckenberg did a great job with their stored procedure chapters in Pro MySQL but given that it wasn't an exclusive development book it didn't go into detail about using stored procedures from other languages, this new book goes into great detail on the subject with dedicated chapters on using stored procedures with PHP, Perl, Python, Java and .Net.&lt;br /&gt;&lt;br /&gt;Having only received the book today I haven't had much of a chance to read it but first impressions look good and as I said previously if it's half as good as Steven Feuerstein's Oracle related books it will be well worth the money.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114623285026286169?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114623285026286169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114623285026286169' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114623285026286169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114623285026286169'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/04/mysql-stored-procedure-programming.html' title='MySQL Stored Procedure Programming (The Book) - 3'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114613861145883893</id><published>2006-04-27T11:12:00.000Z</published><updated>2006-04-28T13:43:21.443Z</updated><title type='text'>Opportunities</title><content type='html'>It's been well mentioned by myself that of late the time I have been able to devote to MySQL has become restricted. Part of this was due to me taking an exciting new job just before Christmas. When I took the decision to close MySQLDevelopment.com down this was in part due to the fact I was using Oracle rather than MySQL and my exposure to real world situations was limited. &lt;br /&gt;&lt;br /&gt;However the day after I made the decision and announced it here my boss asked me to take over the running of a MySQL/PHP based website. The good news at least is that it means it might give me something to actually comment on with regard to the blog, even if it doesn't afford me the time to continue with the site.&lt;br /&gt;&lt;br /&gt;But it's not just good news for me it's also good news for you out there too, the company I work for are looking to take on some new developers. We are looking ideally for people with PHP and Oracle experience but are willing to train good PHP people with limited or no Oracle experience, if you have MySQL skills that would also be a great bonus. The company is based in SW London (England) very close to both over ground rail and tube stations, the atmosphere is relaxed, friendly and informal. &lt;br /&gt;&lt;br /&gt;I personally can't recommend it enough as a place to work and it would be great to hear from you if you are currently looking for a role in the London area and have the skills we are looking for. &lt;br /&gt;&lt;br /&gt;You can use the following link to get some more formal details or you can contact me directly for a more informal chat about the role. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.cwjobs.co.uk/JobSearch/JobDetails.aspx?JobId=21270097&amp;Keywords=&amp;CompanyId=138050&amp;Directory=6"&gt;Click here to see more details of the role...&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114613861145883893?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114613861145883893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114613861145883893' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114613861145883893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114613861145883893'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/04/opportunities.html' title='Opportunities'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114604452648534327</id><published>2006-04-26T09:30:00.000Z</published><updated>2006-04-26T09:44:13.463Z</updated><title type='text'>Fun with dates</title><content type='html'>In response to Kai Voigt's post about unxepected results from dates here is what is going wrong. &lt;br /&gt;&lt;br /&gt;To add and subtract time using + and - you need to use the INTERVAL keyword either before or after the + or - like so..&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select now() - interval 2 day;&lt;br /&gt;+------------------------+&lt;br /&gt;| now() - interval 2 day |&lt;br /&gt;+------------------------+&lt;br /&gt;| 2006-04-24 07:31:02    |&lt;br /&gt;+------------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In Kai's example it's valid to use - on it's own but that handles the date simply as an integer and subtracts the number specified. In small cases as in the example this can seem as if it's the seconds being subtracted but if for example you subtract 100 it simply reduces the number by that amount and not by 1 minute 40 seconds as it sould for a date type. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select now() - 100 day, now();&lt;br /&gt;+----------------+---------------------+&lt;br /&gt;| day            | now()               |&lt;br /&gt;+----------------+---------------------+&lt;br /&gt;| 20060426073122 | 2006-04-26 07:32:22 |&lt;br /&gt;+----------------+---------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can see above the seconds portion of the first "date" is the same where it should be different if it were dealing with it as a time. You can also see that any date formating has been removed (suggesting something odd is going on).&lt;br /&gt;&lt;br /&gt;The second problem is that while you might think that not including the interval would case a problem it becomes a valid SQL statement because it treats the DAY simply as a heading in the output. To change the heading of a column we can either use AS &lt;i&gt;column_name&lt;/i&gt; or simply &lt;i&gt;column_name&lt;/i&gt; after our column definiton, this can be seen like so..&lt;br /&gt;&lt;pre&gt;mysql&gt; select now() - 100 day, now();&lt;br /&gt;+----------------+---------------------+&lt;br /&gt;| day            | now()               |&lt;br /&gt;+----------------+---------------------+&lt;br /&gt;| 20060426073122 | 2006-04-26 07:32:22 |&lt;br /&gt;+----------------+---------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select now() - 100 as "anything you fancy", now();&lt;br /&gt;+--------------------+---------------------+&lt;br /&gt;| anything you fancy | now()               |&lt;br /&gt;+--------------------+---------------------+&lt;br /&gt;|     20060426073738 | 2006-04-26 07:38:38 |&lt;br /&gt;+--------------------+---------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So to add and remove time from dates you need to make sure you use the interval. Something to watch out for when you get unexpected results is the column heading, that might give a clue that all is not right with your SQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114604452648534327?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114604452648534327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114604452648534327' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114604452648534327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114604452648534327'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/04/fun-with-dates.html' title='Fun with dates'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114596227646218307</id><published>2006-04-25T10:35:00.000Z</published><updated>2006-04-25T10:51:16.793Z</updated><title type='text'>MySQLDevelopment.com gets a stay of execution</title><content type='html'>When I posted a few weeks ago about the end of MySQLDevelopment.com it seems the timing was a little off. I was planning to close things down on 30th April simply as it was the end of a month, what I hadn't taken into account was that this would coincide with the MySQL user conference. I won't say too much at the moment but there are plans to use the content on another site which will have some involvment with MySQL themselves, however because of the user conference the people involved won't be able to transfer the content until after the 30th. &lt;br /&gt;&lt;br /&gt;Our visitor numbers are still growing the figures for March were twice those of January so to avoid any distruption of service I won't be pulling the plug until I can make a seemless switch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114596227646218307?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114596227646218307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114596227646218307' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114596227646218307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114596227646218307'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/04/mysqldevelopmentcom-gets-stay-of.html' title='MySQLDevelopment.com gets a stay of execution'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114440203498151923</id><published>2006-04-07T09:15:00.000Z</published><updated>2006-04-07T09:27:15.003Z</updated><title type='text'>MySQLDevelopment Update.</title><content type='html'>I have had a great response from people with regards to the (possible) closure of MySQLDevelopment. It seems people want to keep the site alive in one format or another and I have had a lot of communication from MySQL themselves with regard to keeping the content alive. &lt;br /&gt;&lt;br /&gt;First let me say sorry to all the people who did respond, as suggested in my last post I am really busy at the moment and it's difficult to find the time to reply in a timely fashion. I will be contacting you all individually this weekend. &lt;br /&gt;&lt;br /&gt;Whatever happens it seems that while the site may change a little as from the 1st May MySQLDevelopment will still be available in some form. I'll keep you posted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114440203498151923?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114440203498151923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114440203498151923' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114440203498151923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114440203498151923'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/04/mysqldevelopment-update.html' title='MySQLDevelopment Update.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114380456766910640</id><published>2006-03-31T11:15:00.000Z</published><updated>2006-03-31T11:29:27.690Z</updated><title type='text'>Calling it a day.</title><content type='html'>I have been blogging since last June (is it really that long) and www.mysqldevelopment.com has been going for over a year now. But as the frequency of posts on this blog and updates on the site will testify recently I just haven't had the time I used to have with regards to MySQL. One of the good and bad things with the web is that it's relatively cheap to just leave stuff hanging around where in traditional media, books for example, the costs of continual production mean things go out of print never to be seen again. This means that the web is full of sites and pages which are left untouched for months or years. Most of the time that isn't a problem but often, especially with IT related sites the information can be way off the mark. &lt;br /&gt;&lt;br /&gt;It's with that in mind that as from 1st May 2006 www.mysqldevelopment will no longer exist and this will be my last MySQL related blog entry. I no longer have the time or energy to commit to it and with out that the site won't move forward. Of course if somebody wanted to take it on that would be great but privately I have been looking at ways to move the site forward without success. &lt;br /&gt;&lt;br /&gt;I want to say thanks to all the people who took the time to read my blog and to visit MySQLDevelopment.com and definately a huge thank you to those who contributed to the site over the last year.&lt;br /&gt;&lt;br /&gt;So long and thanks for all the fish.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114380456766910640?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114380456766910640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114380456766910640' title='45 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114380456766910640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114380456766910640'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/03/calling-it-day.html' title='Calling it a day.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>45</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114321701883234351</id><published>2006-03-24T15:46:00.000Z</published><updated>2006-03-24T16:16:58.906Z</updated><title type='text'>Debugging Stored Procedures in MySQL</title><content type='html'>I have recently seen a couple of posts on the MySQL forums with regard to debugging stored procedures in MySQL. The people asking have been Oracle developers who like most people developing stored procedures in Oracle have been using an Oracle built in package called DBMS_OUTPUT. The package essentially accepts text which is then inserted into a buffer which can be viewed after a procedure has been executed (or even during using the correct tools). It got me thinking how easy it would be to add a similar debug method to MySQL so I came up with the following.&lt;br /&gt;&lt;br /&gt;I created a new database called debug, this isn't strictly necessary but I like the idea of having a set area for the debug constructs to reside. I then created a table to hold the output, to keep it simple I simply gave it an id column so we could use the debug across a number of procedures at once, a text column to hold out debug statements and an auto increment column so I could order the results with some certainty. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DROP TABLE IF EXISTS debug.debug;&lt;br /&gt;CREATE TABLE  debug.debug (&lt;br /&gt;  id varchar(100) default NULL,&lt;br /&gt;  debug_output text,&lt;br /&gt;  line_id int(11) NOT NULL auto_increment,&lt;br /&gt;  PRIMARY KEY  (line_id)&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I then created three procedures, debug_on to turn logging on, debug_insert to insert debugging messages and then finally debug_off to stop debugging, display the results and then clear the debug table of records for that id. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DROP PROCEDURE IF EXISTS `debug`.`debug_on` $$&lt;br /&gt;CREATE PROCEDURE `debug_on`(in p_proc_id varchar(100))&lt;br /&gt;begin&lt;br /&gt;  call debug.debug_insert(p_proc_id,concat('Debug Started :',now()));&lt;br /&gt;end $$&lt;br /&gt;&lt;br /&gt;CREATE PROCEDURE `debug_insert`(in p_proc_id varchar(100),in p_debug_info text)&lt;br /&gt;begin&lt;br /&gt;  insert into debug (proc_id,debug_output)&lt;br /&gt;  values (p_proc_id,p_debug_info);&lt;br /&gt;end $$&lt;br /&gt;&lt;br /&gt;CREATE PROCEDURE `debug_off`(in p_proc_id varchar(100))&lt;br /&gt;begin&lt;br /&gt;  call debug.debug_insert(p_proc_id,concat('Debug Ended :',now()));&lt;br /&gt;  select debug_output from debug where proc_id = p_proc_id order by line_id;&lt;br /&gt;  delete from debug where proc_id = p_proc_id;&lt;br /&gt;end $$&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I can now call these from my stored procedures to get debug information like so.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE PROCEDURE test.test_debug()&lt;br /&gt;begin&lt;br /&gt;declare l_proc_id varchar(100) default 'test_debug';&lt;br /&gt;  call debug.debug_on(l_proc_id);&lt;br /&gt;  call debug.debug_insert(l_proc_id,'Testing Debug');&lt;br /&gt;  call debug.debug_off(l_proc_id);&lt;br /&gt;end $$&lt;br /&gt;&lt;br /&gt;mysql&gt; call test.test_debug();&lt;br /&gt;+------------------------------------+&lt;br /&gt;| debug_output                       |&lt;br /&gt;+------------------------------------+&lt;br /&gt;| Debug Started :2006-03-24 16:10:33 |&lt;br /&gt;| Testing Debug                      |&lt;br /&gt;| Debug Ended :2006-03-24 16:10:33   |&lt;br /&gt;+------------------------------------+&lt;br /&gt;3 rows in set (0.20 sec)&lt;br /&gt;&lt;br /&gt;Query OK, 3 rows affected (0.23 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Not rocket science but I'm sure all you Oracle users will be happy, you could of course call the DB DBMS_OUTPUT to make you feel really at home :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114321701883234351?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114321701883234351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114321701883234351' title='61 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114321701883234351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114321701883234351'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/03/debugging-stored-procedures-in-mysql.html' title='Debugging Stored Procedures in MySQL'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>61</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114252520433496994</id><published>2006-03-16T15:51:00.000Z</published><updated>2006-03-16T17:14:06.056Z</updated><title type='text'>Do you really want to comment out that code?</title><content type='html'>Yet again I have been on the MySQL forums and yet again it's given me something to write about. The question was pretty standard simply asking how you comment out code or add comments to MySQL stored routines. However the wording of the question got me thinking. In the past when I have been writing complex stored procedures in Oracle it can be difficult to see where an error is coming from, not necessarily which line is raising the error but which section of code cause the problem. One of the methods I have used in the past is to use the /* */ multi line comment syntax to exclude blocks of code on mass to rule them out quickly, this has proved a good way to narrow down where the root of an error comes from. &lt;br /&gt;&lt;br /&gt;But as you may know MySQL simply removes any comments from the code if it's entered via the command line, it makes no distinction between comments you are adding and code which has been commented out. This isn't a problem when you write procedures in script files and upload them but if you use the command line directly (either typing them in or copy and paste) it means the commented code will be lost forever. &lt;br /&gt;&lt;br /&gt;Yet another example of why you don't want to write stored procedures directly into the command line.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114252520433496994?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114252520433496994/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114252520433496994' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114252520433496994'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114252520433496994'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/03/do-you-really-want-to-comment-out-that.html' title='Do you really want to comment out that code?'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114242310716866841</id><published>2006-03-15T11:14:00.000Z</published><updated>2006-03-15T11:45:07.186Z</updated><title type='text'>Event Scheduler on Mac OS X</title><content type='html'>One of the things I learnt a year ago when I first started working with MySQL stored procedures was that you really need to have the latest version of MySQL running. By the time you have identified a possible bug and noted down the specifics a new version was available which invariably fixed the problem. &lt;br /&gt;&lt;br /&gt;This is also true with release 5.1, I have recently started writing content on the event scheduler over at &lt;a href="http://www.mysqldevelopment.com"&gt;www.mysqldevelopment.com&lt;/a&gt; and found a few bugs early on. Given that 5.1 is still very much in development I tend not to raise bugs these days without first checking on the forums and then making sure I have the very latest release to test against. &lt;br /&gt;&lt;br /&gt;One of the biggest issues I had was that one off events worked fine, but events that fired at intervals didn't. I say they didn't but one of the big problem with testing events is that you have to wait a long time to prove something. I was using 1 minute intervals which didn't work, I also tried 5 and 10 minute intervals also. Testing hour intervals was just about practical but any more than that was just too time consuming. I checked on the forum but there doesn't seem to be a great deal of activity in the event scheduler section at present, so I downloaded a newer version of 5.1 (in this case going from 5.1.6 to 5.1.7), testing again proved positive and it seems whatever the problem had been was now fixed.&lt;br /&gt;&lt;br /&gt;I think the event scheduler is a great new feature and I can't wait to get the content finished, unfortunately it's taking a bit longer than I hoped due to other commitments and also the fact it takes a fair amount of time to testing things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114242310716866841?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114242310716866841/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114242310716866841' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114242310716866841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114242310716866841'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/03/event-scheduler-on-mac-os-x.html' title='Event Scheduler on Mac OS X'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114183263913968563</id><published>2006-03-08T15:34:00.000Z</published><updated>2006-03-08T15:43:59.160Z</updated><title type='text'>Spread the word</title><content type='html'>As you may or may not know I'm a sysop over at the Quest Pipelines MySQL forum. We don't get a great deal of visitors in the MySQL forums there, due in part I guess to the fact the forums on the MySQL website are so good. &lt;br /&gt;&lt;br /&gt;However in addition to running the forums Quest produce a monthly database newsletter which is sent to over 28,000 database professionals. Subjects vary but the general format is an article on Oracle, SQL Server, DB2 and for the last year or so MySQL. For me this is a great way to spread the MySQL word to other database users but unfortunately I'm insanely busy with the day job so I can't submit anything this month. &lt;br /&gt;&lt;br /&gt;So if you have something written or would like to contribute then let the newsletter team know at &lt;br /&gt;&lt;br /&gt;newsletter@quest-pipelines.com&lt;br /&gt;&lt;br /&gt;Or have a look at the latest addition over at the MySQL area of the pipelines site.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.quest-pipelines.com/pipelines/mysql/index.asp"&gt;http://www.quest-pipelines.com/pipelines/mysql/index.asp&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114183263913968563?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114183263913968563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114183263913968563' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114183263913968563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114183263913968563'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/03/spread-word.html' title='Spread the word'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114112951451754249</id><published>2006-02-28T12:07:00.000Z</published><updated>2006-02-28T12:25:14.553Z</updated><title type='text'>The MySQL Prompt</title><content type='html'>Following on from my previous post about tips I have been picking up from the MySQL certification study guide I have another which I think is worth mentioning. &lt;br /&gt;&lt;br /&gt;Personally I had never noticed that the MySQL prompt changes in relation to what went before it. How often have you done something similar to the following.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from emps where emp_name = 'john ;&lt;br /&gt;    '&gt; ;&lt;br /&gt;    '&gt; ';&lt;br /&gt;Empty set (0.01 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You type in a select statement only to open a quote but never close it, personally I always stick in another ; before I realise the mistake and terminate the quote and end the statement correctly. But what I didn't realise before reading the study guide (and making me very unobservant) was that the mysql&gt; prompt changes in response to the currently open quote. In the above example this isn't obvious because it just looks like a continuation but in fact the prompt has been changed to show us that it is expecting a closing single quote. Take for example the following.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from emps&lt;br /&gt;    -&gt; where emp_name = 'john';&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case it gives us the standard -&gt; continuation prompt. Firstly I never even noticed this and secondly even if I did I doubt I would have seen the significance, generally I'm more focused on why the five semi-colons I entered have failed to be recognised. The certification study guide points out that there are in fact 5 prompts. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; &lt;br /&gt;    -&gt;&lt;br /&gt;    '&gt;&lt;br /&gt;    "&gt;&lt;br /&gt;    `&gt;&lt;br /&gt;&lt;/pre&gt;    &lt;br /&gt;This becomes much more relevant when we are entering large complex SQL statements where it might not be obvious where the mistake has occurred. Take this SQL for example.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select e.emp_id, e.emp_name, d.dept_name&lt;br /&gt;    -&gt; from emps e, dept d&lt;br /&gt;    -&gt; where e.dept_id = d.dept_id&lt;br /&gt;    -&gt; and e.emp_name = 'john&lt;br /&gt;    '&gt; and e.dept_id = 1;&lt;br /&gt;    '&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;While this isn't as complex as it could be it’s easy to see in this instance where the problem occurred because our prompt changes from -&gt; to '&gt; on line 5.&lt;br /&gt;&lt;br /&gt;We can use this in combination with the \c tip I mentioned earlier.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select e.emp_id, e.emp_name, d.dept_name&lt;br /&gt;    -&gt; from emps e, dept d&lt;br /&gt;    -&gt; where e.dept_id = d.dept_id&lt;br /&gt;    -&gt; and e.emp_name = 'john&lt;br /&gt;     '&gt; '\c&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114112951451754249?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114112951451754249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114112951451754249' title='25 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114112951451754249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114112951451754249'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/mysql-prompt.html' title='The MySQL Prompt'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>25</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114112843304163316</id><published>2006-02-28T11:45:00.000Z</published><updated>2006-02-28T12:34:49.546Z</updated><title type='text'>Study and You Shall Learn</title><content type='html'>Originally this blog started as a reference for people moving from Oracle to MySQL, over the course of the 5 or so months it's been going I have at times moved away from that and on to other topics. I have tended however to keep it technical and avoided commenting on anything related to the business side of MySQL. Since Christmas my MySQL activities have decreased somewhat but over the last few weeks I've been doing more and more, be that attempting to update this blog or work on new content on &lt;a href="http://www.mysqldevelopment.com"&gt;www.mysqldevelopment.com&lt;/a&gt;. One of the things I have decided to do is take the MySQL certification exams, this isn't some great announcement and I'm a little wary of doing so publicly because I don't want to set a time limit on doing so. &lt;br /&gt;&lt;br /&gt;Anyway on to the point, I have been developing with databases from the very first day of my IT career, mostly this has been with Oracle but also with Microsoft SQL Server, FoxPro, DB2 and Ingress. This has meant that I have picked up a lot of knowledge about databases and also SQL. On the whole this has meant that moving to MySQL has been painless, the few things that I needed to know specifically for MySQL have been easy to pick up. But having started to read the &lt;a href="http://www.amazon.co.uk/exec/obidos/ASIN/0672328127/qid%3D1141127860/026-5906664-7994813"&gt;certification study guide&lt;/a&gt; I can see that there are gaps in my knowledge. Most of these are just small things that while are good to know are not a problem in the day to day operation of MySQL. However there are some really useful things that I have picked up, things which I just wouldn't have known or thought about had I not read the guide  or been told by somebody in the know. I'm sure I'll be posting about more this in the future but here is a small tip I picked up. &lt;br /&gt;&lt;br /&gt;Firstly it's \c, that may be something you use all the time but having worked with Oracle for so long I just got used to entering some rubbish to make the client give me a fresh line. If you like me are unfamiliar with \c then all it does is cancel and clear the command line if you make a mistake while entering a statement. In the old days I would have done something like this....&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; selec t * from emps&lt;br /&gt;    -&gt; where ;&lt;br /&gt;ERROR 1064 (42000): You have an error in your SQL &lt;br /&gt;syntax; check the manual that corresponds to &lt;br /&gt;your MySQL server version for the right syntax to &lt;br /&gt;use near 'selec t * from emps where' at line 1&lt;br /&gt;mysql&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;While I was on the second line I noticed that I had incorrectly typed the SELECT keyword so I terminated the statement by simply entering the ; delimiter. While this doesn't do any harm it does produce an error. Using \c we can do this gracefully like so. &lt;br /&gt;&lt;pre&gt;mysql&gt; selec t * from emps&lt;br /&gt;    -&gt; where \c&lt;br /&gt;mysql&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114112843304163316?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114112843304163316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114112843304163316' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114112843304163316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114112843304163316'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/study-and-you-shall-learn.html' title='Study and You Shall Learn'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114062909909969738</id><published>2006-02-22T17:15:00.000Z</published><updated>2006-02-22T17:24:59.120Z</updated><title type='text'>MySQL Getting More Popular?</title><content type='html'>My web hosting company provide some great statistics for me to look at with relation to my site &lt;a href="http://www.mysqldevelopment.com"&gt;www.mysqldevelopment.com&lt;/a&gt;. It's been interesting watching visitor and hit numbers grow over the last year since the site went live. A year ago for the month of February we had just 251 visits, this year however we have had 3446 in February as of about 5 minutes ago, and there are still 6 days to go in the month. &lt;br /&gt;&lt;br /&gt;But this figure is up drastically from January 2006 and late last year. Each month last year was better than the previous one but growth was steady and we peaked in terms of traffic in November when the site had a lot of activity due to the release of 5.0 and me winning the first week of the 5.0 challenge. But visitor numbers only reached 2847 for November and were around 2500 for the months either side. &lt;br /&gt;&lt;br /&gt;So I was just wondering if this was something thats happened just on &lt;a href="http://www.mysqldevelopment.com"&gt;www.mysqldevelopment.com&lt;/a&gt; or if it was a trend other people in the community were seeing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114062909909969738?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114062909909969738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114062909909969738' title='38 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114062909909969738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114062909909969738'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/mysql-getting-more-popular.html' title='MySQL Getting More Popular?'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>38</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114028084148261807</id><published>2006-02-18T16:15:00.000Z</published><updated>2006-02-18T16:40:41.503Z</updated><title type='text'>WiFi Woes.</title><content type='html'>I have a small network at home running a Windows XP laptop, a Windows desk top and a Mac Mini. I recently move the Mac over to the TV so I could connect it up and watch TV programs I saved using a digital TV gizmo I purchased for my Mac, it's great because it has pretty much made the video machine redundant and recording is a breeze. &lt;br /&gt;&lt;br /&gt;However this meant that the Mac was too far away from the ADSL gateway to be connected via a cable. Given that it was a first generation Mac Mini it didn't come with a wireless card installed. I decided that given that an Airport card would have cost almost twice as much as a windows wireless card and that the Mac Mini at least seems difficult to upgrade yourself, I choose to move the gateway closer to the Mac and get a wireless card for the PC. &lt;br /&gt;&lt;br /&gt;This seemed great for a while, but I have been having plenty of problems with the wireless connection going down which needs a reboot to fix, this as you can imagine is a real pain especially given that my CVS server and MySQL database are on the Mac. This seems to only be a problem with the desk top as the laptop doesn't seem to have the same issues. &lt;br /&gt;&lt;br /&gt;I was hoping to write a fair amount of content for www.mysqldevelopment.com today as I have been a little lax at updating it of late. But the connection has dropped a total of 3 times already. So as I sit here typing this I have the gateway back over near the Windows desktop connected via a cable. This means I'm not able to connect to the Mac but does allow me to vent spleen. &lt;br /&gt;&lt;br /&gt;It's tempting to think that the more complex things become the more problems we have, but then I think back to when I had a spectrum as a kid and you would have to sit through 8 minutes of yellow and blue lines and binary sounds coming out of the tape recorder only to find that at the end it didn't recognise a section of that 48K of code and failed to load that game of Daley Thompsons Decathlon, or the cat decided sitting on the break button was a good idea when you left the thing on all night because you didn't have the energy to finish Jet Set Willy the night before.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114028084148261807?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114028084148261807/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114028084148261807' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114028084148261807'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114028084148261807'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/wifi-woes.html' title='WiFi Woes.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114027018693198339</id><published>2006-02-18T13:29:00.000Z</published><updated>2006-02-18T13:44:38.566Z</updated><title type='text'>Index</title><content type='html'>I got an email from Peter Mescalchin a few weeks ago asking me to check a problem he was having with a select statment. He has two fairly large tables one of 14,000 rows and another of 79,994 he is joining these two tables together using a column on the second which has an index. With the index in place the query executes quickly (0.19 seconds on my machine) but when the index is removed his machine hangs and on mine a P4 Hyperthread 2.8Mhz machine one of the CPU threads is kept at 70-80%, it finally completed 1 Hour, 16 Minutes, 2.16 seconds later. A similar thing happened on the Mac but the connect timed out before it returned.&lt;br /&gt;&lt;br /&gt;I'm not a performance expert so I wasn't able to give Peter much of an answer other than to confirm what he was seeing. Anybody have any idea why there is such a dramatic difference?&lt;br /&gt;&lt;br /&gt;For those looking to test here are the details Peter was using. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Two tables:&lt;br /&gt;&lt;br /&gt; CREATE TABLE `first` (&lt;br /&gt;   `id` smallint(5) unsigned NOT NULL,&lt;br /&gt;   `name` varchar(20) collate utf8_unicode_ci NOT NULL,&lt;br /&gt;   PRIMARY KEY  (`id`)&lt;br /&gt; ) ENGINE=MyISAM DEFAULT &lt;br /&gt;   CHARSET=utf8 COLLATE=utf8_unicode_ci;&lt;br /&gt;&lt;br /&gt; CREATE TABLE `second` (&lt;br /&gt;   `id` int(10) unsigned NOT NULL auto_increment,&lt;br /&gt;   `firstid` smallint(5) unsigned NOT NULL,&lt;br /&gt;   PRIMARY KEY  (`id`),&lt;br /&gt;   KEY `firstid` (`firstid`)&lt;br /&gt; ) ENGINE=MyISAM DEFAULT &lt;br /&gt;   CHARSET=utf8 COLLATE=utf8_unicode_ci;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt; Table `first` holds 14,000 rows, table `second` holds 79994 with&lt;br /&gt; `second.firstid` a forgien key to `first.id`. Now to execute a query&lt;br /&gt; to return rows from `first` that are not referenced in `second`.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; SELECT `first`.*&lt;br /&gt; FROM `first` LEFT JOIN `second` &lt;br /&gt; ON (`first`.id = `second`.firstid)&lt;br /&gt; WHERE (`second`.firstid IS NULL)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt; Then delete the index on second.firstid.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114027018693198339?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114027018693198339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114027018693198339' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114027018693198339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114027018693198339'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/index.html' title='Index'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-114024991248157676</id><published>2006-02-18T07:40:00.000Z</published><updated>2006-02-18T08:05:12.500Z</updated><title type='text'>5.1.6 On Mac OS X</title><content type='html'>I have finally found sometime this weekend to update www.mysqldevelopment.com. So in the spirit of the site I'm looking forward and adding content on some of the new features in 5.1, first up it's the event scheduler. &lt;br /&gt;&lt;br /&gt;I have been using my Mac less and less recently simply because I have been using it as a media centre and it now lives over by the TV, I generally connect remotely via putty or VNC. So given that I was on my Windows PC this morning I decided to install the latest release of 5.1 on there. &lt;br /&gt;&lt;br /&gt;The download and install went perfectly and I started up the MySQL command line ready to have a play with the event scheduler. So I ran&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; SHOW GLOBAL VARIABLES LIKE 'event%';&lt;br /&gt;+-----------------+-------+&lt;br /&gt;| Variable_name   | Value |&lt;br /&gt;+-----------------+-------+&lt;br /&gt;| event_scheduler | OFF   |&lt;br /&gt;+-----------------+-------+&lt;br /&gt;1 row in set (0.01 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Great off to a good start, next up I have to set the event_scheduler variable to ON.... &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;ERROR 2013 (HY000): Lost connection to MySQL server during query&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Oops.. memories of the early work I did on mysqldevelopment.com with 5.0.1 came flooding back, having worked with recent versions of MySQL 5.0 which are totally stable  it's easy to forget that 5.1.6 is still in the development phase. I remembered Markus Popp mentioning that the event scheduler had problems on windows and it seems it does.&lt;br /&gt;&lt;br /&gt;So I connected to the Mac via VNC and downloaded 5.1.6 for the Mac OS X 10.3 (yep behind the times at bit on that as well). In the past I have had plenty of problems upgrading MySQL on the Mac, I'll be honest and say that was more to do with my lack of experience of the Darwin command line than anything else, but it seems I must have picked something up as this time it was really simple. I tend to make things easy for myself in that I just to clear out the old system and install the new one right on top, I don't have anything worth keeping on the Mac's MySQL database so that makes things relatively easy. &lt;br /&gt;&lt;br /&gt;So I rebooted, went into the terminal and typed MySQL.... &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;~ $ mysql&lt;br /&gt;Welcome to the MySQL monitor.  Commands end with ; or \g.&lt;br /&gt;Your MySQL connection id is 4 to server version: 5.1.6-alpha&lt;br /&gt;&lt;br /&gt;Type 'help;' or '\h' for help. Type '\c' to clear the buffer.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then I tried to turn on the event scheduler&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; set global event_scheduler = ON;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So that’s it, I'm all set ready to rock and roll with 5.1.6 and ready to test the event scheduler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-114024991248157676?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/114024991248157676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=114024991248157676' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114024991248157676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/114024991248157676'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/516-on-mac-os-x.html' title='5.1.6 On Mac OS X'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113949920377173647</id><published>2006-02-09T15:00:00.000Z</published><updated>2006-02-09T15:33:23.826Z</updated><title type='text'>Cartesian Joins are Useful (Honest)</title><content type='html'>For those that don't know a cartesian join is one that produces a cartesian product. A cartesian product is the result of joining two sets of data in such a way that all rows in one set are joined with all rows in the other. In MySQL this happens when we have two tables in an SQL statement but no join statement. For example...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from emp_dept;&lt;br /&gt;+--------+---------+&lt;br /&gt;| emp_id | dept_id |&lt;br /&gt;+--------+---------+&lt;br /&gt;|      1 |       1 |&lt;br /&gt;|      2 |       1 |&lt;br /&gt;|      3 |       2 |&lt;br /&gt;|      4 |       2 |&lt;br /&gt;+--------+---------+&lt;br /&gt;4 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from dept;&lt;br /&gt;+---------+------+&lt;br /&gt;| dept_id | name |&lt;br /&gt;+---------+------+&lt;br /&gt;|       1 | IT   |&lt;br /&gt;|       2 | HR   |&lt;br /&gt;+---------+------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Normally these two tables would be joined using a join condition on dept_id so that we return only the rows where a match is found.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select emp_id, name &lt;br /&gt;       from emp_dept e join dept d &lt;br /&gt;       on e.dept_id = d.dept_id;&lt;br /&gt;+--------+------+&lt;br /&gt;| emp_id | name |&lt;br /&gt;+--------+------+&lt;br /&gt;|      1 | IT   |&lt;br /&gt;|      2 | IT   |&lt;br /&gt;|      3 | HR   |&lt;br /&gt;|      4 | HR   |&lt;br /&gt;+--------+------+&lt;br /&gt;4 rows in set (0.26 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However if we remove the join each row in emp_dept is joined with dept if a match exists or not.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select emp_id, name from emp_dept, dept;&lt;br /&gt;+--------+------+&lt;br /&gt;| emp_id | name |&lt;br /&gt;+--------+------+&lt;br /&gt;|      1 | IT   |&lt;br /&gt;|      1 | HR   |&lt;br /&gt;|      2 | IT   |&lt;br /&gt;|      2 | HR   |&lt;br /&gt;|      3 | IT   |&lt;br /&gt;|      3 | HR   |&lt;br /&gt;|      4 | IT   |&lt;br /&gt;|      4 | HR   |&lt;br /&gt;+--------+------+&lt;br /&gt;8 rows in set (0.01 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a cartesian product. In most cases this isn't a great idea, I had a problem last year where the assumption was that there was a 1 to 1 relationship in a table join, the introduction of some code broke this rule and it resulted in a select returning 3 million rows where once it only returned 150 or so. The users were not happy when their application took 5 minutes to load when previously it took seconds.&lt;br /&gt;&lt;br /&gt;Result sets can get large quickly because the amount of data in the select is the number of rows in Table A * the number of rows in Table B, if you have more than two tables this multiplies at an alarming rate.&lt;br /&gt;&lt;br /&gt;But there are times when we can use this to our advantage. I'm working on a site which needs some combinations stored for a game engine, there are 6561 different combinations and I didn't fancy having to type them in by hand. So what I did was create a dummy table with all values I needed in each position, I then used a cartesian join by having a copy of the table for as many columns as I needed.  &lt;br /&gt;&lt;br /&gt;So lets take a simplified example, if we want all the combinations of 1,2 and 3 using 2 columns we can do this like so.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from dummy_table;&lt;br /&gt;+------+&lt;br /&gt;| nums |&lt;br /&gt;+------+&lt;br /&gt;| 1    |&lt;br /&gt;| 2    |&lt;br /&gt;| 3    |&lt;br /&gt;+------+&lt;br /&gt;3 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select concat(d1.nums,d2.nums) &lt;br /&gt;       from dummy_table d1, dummy_table d2;&lt;br /&gt;+-------------------------+&lt;br /&gt;| concat(d1.nums,d2.nums) |&lt;br /&gt;+-------------------------+&lt;br /&gt;| 11                      |&lt;br /&gt;| 21                      |&lt;br /&gt;| 31                      |&lt;br /&gt;| 12                      |&lt;br /&gt;| 22                      |&lt;br /&gt;| 32                      |&lt;br /&gt;| 13                      |&lt;br /&gt;| 23                      |&lt;br /&gt;| 33                      |&lt;br /&gt;+-------------------------+&lt;br /&gt;9 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113949920377173647?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113949920377173647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113949920377173647' title='48 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113949920377173647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113949920377173647'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/cartesian-joins-are-useful-honest.html' title='Cartesian Joins are Useful (Honest)'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>48</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113941459458493373</id><published>2006-02-08T15:21:00.000Z</published><updated>2006-02-09T09:52:48.170Z</updated><title type='text'>More in More Out</title><content type='html'>I've been busy of late, most of my time seems to be taken up with fixing layout bugs in my web applications introduced when I spend all day testing in FireFox which works perfectly, then only to have a quick test on I.E. to notice that there is a tiny portion of the page which is out and in the most ugly way possible. I then tend to mess the whole page up trying to track down where it might have come from. I suppose I should have learnt to test in I.E. early in the process but that means leaving the debugger and CSS edit facilities of FireFox behind. &lt;br /&gt;&lt;br /&gt;Anyway back to the point, this means I have less and less time to devote to MySQL these days, but that doesn't stop me popping into the MySQL &lt;a href="http://forums.mysql.com/"&gt;forums&lt;/a&gt; a couple of times a day (for no other reason than to stop me going crazy messing around with I.E.). I've posted a few times here recently on the need to be as descriptive as possible but one thing that seems to be becoming very important when answering is version information. &lt;br /&gt;&lt;br /&gt;Firstly there are many people keen to try the new features of MySQL such as stored procedures, triggers and views, as we know they are only available from version 5 (triggers only from 5.0.3) so if people included the version number when asking a question related to the subject it would be immediately obvious they were using the wrong version. If nothing else it may even prompt the person asking the question to consider if the feature they are using is available in their version. &lt;br /&gt;&lt;br /&gt;Secondly there are plenty of questions which relate to fairly complex SQL statements, many of those can be quickly answered using a sub select but as you may know this is only available from version 4.1, many of the people using the forums are using MySQL via their web hosting account and many of those are still on version 4.0 and below. The obvious thing to do in such cases is to give an answer for both 4.0 and 4.1 versions but often I don't have enough time to answer for one version let alone two, especially when the query is complex and needs a bit of care to give a full answer with an example. &lt;br /&gt;&lt;br /&gt;This leads to me having to filter the questions based on how much information the user has given or more of a problem the first answer is simply a request for version information, with the way the site operates this means people in different time zones can wait up to a day for a decent reply. &lt;br /&gt;&lt;br /&gt;I can see one of two ways to deal with this, try and educate users of the forums to include as much information as possible including the version of MySQL they are using or add a selection box on the forum page to specify the version number prior to asking the question, make this mandatory (with a unknown option, and also a default option in your profile) so that it prompts people to at least consider the question may be version related.&lt;br /&gt;&lt;br /&gt;The problem of course with the first is that many people asking questions only do so once, they get the answer to their question and they never come back. The problem with the second is that this is something only MySQL AB themselves can control.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113941459458493373?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113941459458493373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113941459458493373' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113941459458493373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113941459458493373'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/more-in-more-out.html' title='More in More Out'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113898533743548677</id><published>2006-02-03T16:26:00.000Z</published><updated>2006-02-03T16:49:38.740Z</updated><title type='text'>Keeping it short.</title><content type='html'>A recent post in the MySQL Stored Procedure forum reminded me of the old days, the post was with regard to a problematic stored procedure which had a rather long name. The name had nothing to do with the problem but it got me thinking about naming conventions and documenting code to make it more readable. &lt;br /&gt;&lt;br /&gt;I'm all for naming things with an appropriate name but there are times when it can be taken too far. One particular example was a system I worked on a few years ago, every table had two columns called unique_identifier and parent_identifier. Every record had a unique identifying number and the ability to store the unique identifier of it's parent, I'll ignore the fact this wasn't the greatest way to design the database for now. &lt;br /&gt;&lt;br /&gt;The problem was that these columns were used on a regular basis, pretty much in every SQL statement that joined two tables in the system. This meant that the consulting team spent most of their programming time typing these things out in full (which also included typos on a regular basis). The development team could have used unique_id or even uid and everybody would still have know what the columns were used for but they went for the fully monty.&lt;br /&gt;&lt;br /&gt;Don't get me wrong I'm definitely into using descriptive names but there comes a time when you need to think about how practical it's going to be when you have to type 60 extra characters per SQL statement. &lt;br /&gt;&lt;br /&gt;I had a meeting with one of the original development team and he informed me the decision was taken because Visual FoxPro allowed 32 character column names where FoxPro 2.0 only ever allowed 8 characters, he said it was a decision that they wish the had never taken.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113898533743548677?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113898533743548677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113898533743548677' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113898533743548677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113898533743548677'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/02/keeping-it-short.html' title='Keeping it short.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113818161843065761</id><published>2006-01-25T09:15:00.000Z</published><updated>2006-01-25T09:33:38.450Z</updated><title type='text'>Improving your SQL skills</title><content type='html'>I used to be almost exclusively a database developer, writing complex queries and stored procedures in Oracle and MySQL. Of late I've been doing more and more web based work, HTML, JavaScript, CSS, PHP and PERL, this means of course that I'm doing less and less SQL especially the more complex stuff that I would have been doing in the past. &lt;br /&gt;&lt;br /&gt;Personally I've been using SQL long enough that while it might not flow from my fingers as it did previously with a bit of thinking it comes back fairly quickly. I tend to think of it like fitness, if you go to the gym regularly your fitness levels improve quickly, slack off and they drop back down almost as fast.&lt;br /&gt;&lt;br /&gt;To keep my SQL skills "fit" I visit another sort of gym, the MySQL Forums, to be exact the Newbie forum. In that forum there are plenty of people offering you the chance of a mental work out at all skill levels, because of it's very nature there are all sorts of questions which often need a clever solution. While it’s a pain to most people the lack of support for sub-queries in MySQL 4.0 is great for a work out as it often makes you think a little harder about how to tackle a problem you might normally throw a sub-query at.&lt;br /&gt;&lt;br /&gt;If you ever become too fit for the Newbie forum there are plenty of others, just like a gym has different equipment to work different areas of your body, the MySQL Forum has different sections to raise you SQL fitness levels further, the General and Performance being good ones to put mass on those SQL muscles. &lt;br /&gt;&lt;br /&gt;The great thing about these questions is that during your normal working year you might never get to use some of the features needed to answer them, there is nothing worse that your boss dumping a set of reports requirements on your desk and having no idea how to even start constructing the SQL. But if you have been working out at the SQL gym you’re likely to have come across a few methods to get started. &lt;br /&gt;&lt;br /&gt;So why not do what the government health departments keep telling us and spent 30 minutes a day in the gym.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113818161843065761?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113818161843065761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113818161843065761' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113818161843065761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113818161843065761'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/improving-your-sql-skills.html' title='Improving your SQL skills'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113774880922334417</id><published>2006-01-20T08:54:00.000Z</published><updated>2006-01-20T09:20:09.240Z</updated><title type='text'>XML - Using MySQL with AJAX (part 2)</title><content type='html'>When I suggested MySQL had a big part to play in the X of AJAX it was more of a case throwing ideas into the ether than any solid or contrived plan. My initial thoughts were simply to allow the web server to talk directly with MySQL and return the XML needed for a give select statement. The goal was to avoid the normal middle stage of using some sort of scripting to accept the statement, call a standard MySQL select and process this into an XML format. Something along the lines of MySQL being an XML factory where you pass the select and MySQL directly passes back the XML.&lt;br /&gt;&lt;br /&gt;Some great ideas have been suggested, mainly around using --xml to format the output directly from the command line, which would interact with Apache by a module. I've been able to knock up a Perl program which is capable of doing this but it's raised more concerns than solid answers. &lt;br /&gt;&lt;br /&gt;When I looked at this more closely the immediate thing was how unsecured the whole thing would be, not so much unsecured as completely open in fact. The original idea was to essentially call MySQL directly from JavaScript (via the web server) but that would mean having the select statement, or at least the table and column names visible in the JavaScript. There would be no way to secure that without some level in between.&lt;br /&gt;&lt;br /&gt;The original post in fact wasn't suggesting that we interface directly with MySQL as it currently is, it was more of a look into the future to see where for example stored procedures could be taken. The idea would have been to use stored procedures to accept parameters which were then turned in select statements and XML returned, that way we could at least avoid the potential of SQL injection attacks, or people simply calling SQL statements at will. &lt;br /&gt;&lt;br /&gt;Don't get me wrong the ideas have been great and I'm still confident MySQL can be central in an AJAX system in the way suggested, but maybe not with the minimal number of levels I might have first envisaged.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113774880922334417?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113774880922334417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113774880922334417' title='59 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113774880922334417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113774880922334417'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/xml-using-mysql-with-ajax-part-2.html' title='XML - Using MySQL with AJAX (part 2)'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>59</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113767866073863598</id><published>2006-01-19T13:32:00.000Z</published><updated>2006-01-19T13:51:00.756Z</updated><title type='text'>WiFi Access</title><content type='html'>An article on the BBC News website today suggests that WiFi is "slow to enthuse consumers". The report by Toshiba suggests that only 11% of people used WiFi away from home, while at home over 50% used WiFi to access the internet. &lt;br /&gt;&lt;br /&gt;Personally I don't think for a second that it's a case of lack of enthusiams by consumers which is stopping people getting on line on their laptops when away from home. I'd love to be able to logon when I'm out and about especially since I just got a WiFi enabled mobile phone. I did a little bit of research using the WiFi alliance web site which lists WiFi hot spots in the UK (as well as the rest of the world). Within a 2 mile radius of my home there are 6 hotspots, all of which in pubs. While I enjoy going to the pub it's the last place I want to take my £1000 laptop for the evening. Extending the search to 20 a mile radius and I'm up to 251 and this time there are a few coffee shops but few in a place I'm actually likely to be. &lt;br /&gt;&lt;br /&gt;Be here comes the point, I then check for free hotspots, there are just 2 in a 20 miles radius. Checking the price plans for the pay services reveal that it's going to cost me cira £30 a month to get connected. Add on top of that the £2 for a coffee or £3 for a pint of beer I'll have to pay to sit in the pub of cafe while surfing and that soon starts to add up. Add that on to the £20 I'm already paying for internet access at home and thats a hell of a lot of money. &lt;br /&gt;&lt;br /&gt;Perhaps the headline should have been.... &lt;br /&gt;&lt;br /&gt;"Cost of WiFi fails to enthuse consumers"&lt;br /&gt;&lt;br /&gt;&lt;a href="http://news.bbc.co.uk/1/hi/technology/4624298.stm"&gt;BBC News : Wi-fi slow to enthuse consumers&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113767866073863598?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113767866073863598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113767866073863598' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113767866073863598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113767866073863598'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/wifi-access.html' title='WiFi Access'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113767164557953602</id><published>2006-01-19T11:45:00.000Z</published><updated>2006-01-19T11:54:05.596Z</updated><title type='text'>MySQL Stored Procedure Programming (The Book) - 2</title><content type='html'>This is the second time* I've mentioned the O'Reilly MySQL Stored Procedure Programming book on this blog. I'm mentioning it again because I suddenly realised that the release date of March 2006 isn't anywhere near as far away as I thought it was, when your in 2005 any date in 2006 seems like a bit of time away but on reflection and now being half way through the first month of the year it seems to be creeping up with even increasing speed. &lt;br /&gt;&lt;br /&gt;With that in mind I placed my order with Amazon.co.uk today, it's avaliable on pre order and with a 30% discount on the cover price. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.co.uk/exec/obidos/ASIN/0596100892/qid=1137670613/sr=1-6/ref=sr_1_3_6/026-9997015-4638826"&gt;Click here to view the book on Amazon.co.uk&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have all 7 of Steven Feuerstein's Oracle books and as I said previously if it's half as good as those it will be a great book. &lt;br /&gt;&lt;br /&gt;*&lt;span style="font-style:italic;"&gt;I have no vested interest or association with the book, O'reilly or the authors. I just know it's going to be a great book. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113767164557953602?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113767164557953602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113767164557953602' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113767164557953602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113767164557953602'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/mysql-stored-procedure-programming.html' title='MySQL Stored Procedure Programming (The Book) - 2'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113759867094958274</id><published>2006-01-18T15:18:00.000Z</published><updated>2006-01-18T16:30:15.416Z</updated><title type='text'>Don't be afraid to get it wrong.</title><content type='html'>While it may not be a great thing to admit but some of my best lessons have come at the result of initial failure, taking a backup before deleting all the data in a table comes to mind. When I first started this blog and even more so when it was added to PlanetMySQL I made a decision that not being 100% sure about something wasn't a reason not to post it. Don't get me wrong I always make every effort to check my facts and in the Tom Kyte mode I'll always (or at least try) and give real world examples to prove my point. &lt;br /&gt;&lt;br /&gt;But there are often times when I'll post something which is inaccurate or just plain wrong. There are broadly two things you can do in such circumstances when people correct you (and believe me they will), you can accept you made a mistake, correct any errors and learn from it. Or you can just give up and never post again for fear of looking a total fool. The fact I've made mistakes and I'm still blogging will give you some indication of which group I fit into. &lt;br /&gt;&lt;br /&gt;This slightly confessional blog is in response to a post I made a few days ago with regard to XML and MySQL. The central theme was a vision of MySQL as a key component in AJAX where rather than the added complexity of a language such as PHP, PERL etc MySQL took on the role of serving the XML directly from the web server. In it I pointed to Oracles SET MARKUP HTML command and longed for a MySQL equivalent, or at least an equivalent XML version. If you read the comments on that post you will see that MySQL does support such a feature, it's not exactly what I was talking about but it's close enough to have been mentioned. I'll say that I was at least in the past aware of the feature but when I was checking out my facts prior to posting I couldn't find mention of it on the MySQL site, I just thought I was mistaken and it was a feature of some other software. &lt;br /&gt;&lt;br /&gt;The point is that you shouldn't sit in the shadows fearful of getting something wrong, if you have been worried about blogging or answering questions on forums for fear of being wrong you won't get very far. &lt;br /&gt;&lt;br /&gt;Yesterdays mistake makers may well be tomorrows experts*&lt;br /&gt;&lt;br /&gt;*&lt;span style="font-style:italic;"&gt;Providing they learn from those mistakes.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113759867094958274?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113759867094958274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113759867094958274' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113759867094958274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113759867094958274'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/dont-be-afraid-to-get-it-wrong.html' title='Don&apos;t be afraid to get it wrong.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113742768928330192</id><published>2006-01-16T15:36:00.000Z</published><updated>2006-01-16T16:12:31.870Z</updated><title type='text'>XML - Using MySQL with AJAX</title><content type='html'>There has been a few posts on PlanetMySQL recently with regard to an XML, firstly the new XML functions for extracting information from XML stored in standard tables and more recently an XML storage engine.&lt;br /&gt;&lt;br /&gt;It got me thinking, I've posted recently about working with AJAX and I've been developing some AJAX functionality for our clients. It seems to me that part of the goal with AJAX is to give a better user experience but also to reduce the amount of traffic to the server by only loading what's needed, when it's needed. Not as in our case a refresh of the page (along with the associated images). There is a balancing act between making the page functional and also keeping the amount of Javascript down, it's easy to shift alot of HTML from the initial page only to replace it with complex JavaScript functionality to manipulate XML which is returned in the xmlHttpRequest calls. &lt;br /&gt;&lt;br /&gt;I've used Oracle's HTML DB which is an Apache Module which calls Oracle stored procedures and returns the output to the requesting browser, this allows people who are comfortable with PL/SQL to develop web applications from within Oracle, no need for PHP,PERL etc. In fact this is the very reason I became involved with MySQL, looking for an equivalent technology in MySQL. &lt;br /&gt;&lt;br /&gt;What would be great is if we could use an Apache module to return the contents of a MySQL stored procedure, this procedure could accept parameters and return an XML document straight from Apache, no additional PHP layer just an HTTP response directly from the webserver interacting with MySQL. &lt;br /&gt;&lt;br /&gt;Another great feature of Oracle is SQL*Plus' ability to export in HTML, using the command SET MARKUP HTML ON any subsequent query is output on HTML table format. Something I think would benefit MySQL would be the possiblity of outputting data in XML format, that way we could even remove the stored procedure layer in the above example. &lt;br /&gt;&lt;br /&gt;That would fit fantastically into AJAX. Something like the following cold have uses far and above just AJAX...,&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from emps;&lt;br /&gt;+-------+---------+&lt;br /&gt;| empno | ename   |&lt;br /&gt;+-------+---------+&lt;br /&gt;| 1     | Dave    |&lt;br /&gt;+-------+---------+&lt;br /&gt;| 2     | John    |&lt;br /&gt;+-------+---------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; set output xml &lt;br /&gt;&lt;br /&gt;mysql&gt; select * from emps;&lt;br /&gt;&lt;br /&gt;&amp;lt;emps&amp;gt;&lt;br /&gt;  &amp;lt;row&amp;gt;&lt;br /&gt;   &amp;lt;empno&amp;gt;1&amp;lt;/empno&amp;gt;&lt;br /&gt;   &amp;lt;ename&amp;gt;Dave&amp;lt;/ename&amp;gt;&lt;br /&gt;  &amp;lt;/row&amp;gt;&lt;br /&gt;  &amp;lt;row&amp;gt;&lt;br /&gt;   &amp;lt;empno&amp;gt;2&amp;lt;/empno&amp;gt;&lt;br /&gt;   &amp;lt;ename&amp;gt;John&amp;lt;/ename&amp;gt;&lt;br /&gt;  &amp;lt;/row&amp;gt;&lt;br /&gt;&amp;lt;/emps&amp;gt;&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113742768928330192?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113742768928330192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113742768928330192' title='85 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113742768928330192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113742768928330192'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/xml-using-mysql-with-ajax.html' title='XML - Using MySQL with AJAX'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>85</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113740467394536177</id><published>2006-01-16T09:33:00.000Z</published><updated>2006-01-16T09:45:03.110Z</updated><title type='text'>Event Scheduler</title><content type='html'>Release 5.1 of MySQL comes with a new event scheduler, this is great news and further moves the MySQL database away from just a data store, something which began with the introduction of Stored Procedures and Triggers in 5.0.&lt;br /&gt;&lt;br /&gt;The event scheduler will allow you to run an SQL command at a specific time, this is great for maintenance purposes. It's possible to run the command a single time or set up and interval and run it multiple times. What's also great is that you can use DDL, DML and even compound statements which allows SQL/PSM syntax to handle processing as part of the command.&lt;br /&gt;&lt;br /&gt;I'll admit to not having downloading and installing 5.1 as yet but this is definitely something I'll be using. As an Oracle user I've been using Oracle's version DBMS_JOB for a while and this looks to be as good, if not better due to the easy method of adding events.&lt;br /&gt;&lt;br /&gt;Having said all this often in Oracle I have often preferred to use a combination of SQL*Plus and CRON due to the ability to process the output in Unix/Linux after the job has run. For those using a MySQL version other than 5.1 CRON does offer a great way of doing a similar job to the new event scheduler.&lt;br /&gt;&lt;br /&gt;You can see an introduction to the event scheduler here.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/tech-resources/articles/event-feature.html"&gt;http://dev.mysql.com/tech-resources/articles/event-feature.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113740467394536177?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113740467394536177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113740467394536177' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113740467394536177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113740467394536177'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/event-scheduler.html' title='Event Scheduler'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113740385724309421</id><published>2006-01-16T09:02:00.000Z</published><updated>2006-01-16T09:30:57.263Z</updated><title type='text'>Blue Screen of Death and other Myths.</title><content type='html'>I was half listening to a radio show yesterday about the Consumer Electronics Show, the general feeling that this year there wasn't really a wow moment and nothing earth shatteringly new had been shown. One of the guests was even rather dismissive of Apples new Intel based laptop range (which while a major shift from Apple isn't actually a major step forward in general). But one of the things that was said was about the unreliablility of Windows, the dreaded Blue Screen of Death (BSoD) was mention and how often it happens. &lt;br /&gt;&lt;br /&gt;It got me thinking, is that really true? I've been running windows (in it's various forms) since the early 90's and while it crashed with regularity in the earlly days I personally haven't had many problems for years. At work I ran NT for almost 3 years without even turning the PC off and only twice did I get the BSoD, after a quick restart everything was fine. &lt;br /&gt;&lt;br /&gt;At home with XP it's just as good, while the PC doesn't stay on for days I've never had a BSoD and from what I recall never had to hold the off button down to clear a crash. I got a Mac last year and while that has a great reputation for stability I have had to hold the off button on a couple of occassions, am I to infer that Macs are buggy and unreliable?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113740385724309421?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113740385724309421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113740385724309421' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113740385724309421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113740385724309421'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/blue-screen-of-death-and-other-myths.html' title='Blue Screen of Death and other Myths.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113680304383370614</id><published>2006-01-09T10:27:00.000Z</published><updated>2006-01-09T10:39:52.573Z</updated><title type='text'>AJAX, iPods and the MySQL Guild</title><content type='html'>I took a little break over the Christmas period and avoided using the computer as much as possible, so this is my first blog of the year. I mentioned AJAX in my last blog and in the time since then my demo was completed (after a few teething problems). I gave a demo to my boss and a couple of clients on Friday and it went down really well, it's often difficult with clients as people are so used to computers these days people have a certain level of expectation and while us as technical people can see the benefits of something like AJAX it's often lost in translation somewhere along the line. Thankfully in this case they were really keen and we are in the process of setting up a test to see if it improves the clients business.&lt;br /&gt;&lt;br /&gt;Last week I recieved my iPod Nano, the prize from the MySQL 5.0 competition. It had been a while in coming due to me not being home when the delivery company called before Christmas. It's small, very small but sounds great, it's also black (my prefered colour) and the 4Gb version which I was suprised and greatfull to MySQL for. &lt;br /&gt;&lt;br /&gt;Finally I have had the great honour of being added to the MySQL Guild, as both a writer and expert. It's great to have my work recognised over the last year and this is the icing on the cake. You can see a list of all the guild members here &lt;a href="http://dev.mysql.com/guilds/"&gt;http://dev.mysql.com/guilds/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113680304383370614?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113680304383370614/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113680304383370614' title='24 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113680304383370614'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113680304383370614'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2006/01/ajax-ipods-and-mysql-guild.html' title='AJAX, iPods and the MySQL Guild'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>24</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113578887619885173</id><published>2005-12-28T16:38:00.000Z</published><updated>2005-12-28T16:54:36.216Z</updated><title type='text'>AJAX</title><content type='html'>Depending on your education or where you live AJAX can mean one of at least four things, if you studied classics you will known Ajax from Homer's Iliad, if your in to Football then you might know Ajax of Amsterdam and if you live in the UK and are over 30 you will know Ajax toilet cleaner. For me fitting in all three categories it summons up visions of a football playing Greek hell bent on cleaning the toilets after the match. &lt;br /&gt;&lt;br /&gt;Anyway, I recently started a new job as a web/DB developer, the first few weeks have been heavy on the database side, working with some large data sets trying to load and then extract information for a bulk email system (boo hiss you all say). Anyway, I've now been asked to investigate AJAX, which as you may know stands for Asynchronous JavaScript and XML. AJAX isn't a language but a web development technique for building sites which don't need constant refreshing of the sites pages, instead small sections of the pages are updated using specific calls to the server to return XML which is then processed by Java to update the page. &lt;br /&gt;&lt;br /&gt;This means web sites can behave much more like client server apps, so that list can populated when another value on the page changes, validation can take place almost instantly and so on. &lt;br /&gt;&lt;br /&gt;I'm building a prototype of an exisitng web site we run, for this I'm using PHP and MySQL, this seems a great choice but the thing with AJAX is that the language is unimportant. One thing I have found however is that while there is plenty of buzz around on the web about AJAX, examples seem to be hard to come by, it may be that there are plenty of examples around but that it's swamped by all the blog and magazine articles giving us just a taste. I've managed however to knock something up, it needs a bit of work but it's looking good so far.&lt;br /&gt;&lt;br /&gt;Anyway I'll keep you posted and if it works out I'll provide a URL of the prototype.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113578887619885173?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113578887619885173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113578887619885173' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113578887619885173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113578887619885173'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/ajax.html' title='AJAX'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113526071349024943</id><published>2005-12-22T13:47:00.000Z</published><updated>2005-12-22T14:11:53.506Z</updated><title type='text'>Read the ******* Manual</title><content type='html'>First let me say I'm not a prude, but neither do I have a mouth like a toilet. But I do find the acronym RTFM incredibly offensive, it may be that some people using it don't actually know what it means and it can be said the F stands for something other than the obvious but either way I don't like it. I've nothing wrong with acronyms but what I don't like about it is the idea that you're swearing at somebody you don't even know, who in their ignorance for one reason or other didn't read a manual. Would you for example say to somebody who asks you the time "Buy a ******* watch". The other problem is often people don't actually tell you which manual it is your supposed to go and ******* read. &lt;br /&gt;&lt;br /&gt;Anyway the point of this little rant was to tell you to go and read a manual. Well not just any manual but the MySQL Reference manual. From time to time I'll have a browse to see what's in there and from time to time I pickup some great tips. For example, I've mentioned many times (in today’s earlier blog for example) that creating script files for stored procedures and running them using &lt;span style="font-weight:bold;"&gt;source &lt;span style="font-style:italic;"&gt;filename&lt;/span&gt;&lt;/span&gt; is a great idea, what I didn't know is that you can also use &lt;span style="font-weight:bold;"&gt;\. &lt;span style="font-style:italic;"&gt;filename&lt;/span&gt;&lt;/span&gt; to do the same thing. &lt;br /&gt;&lt;br /&gt;It's not the most amazing thing you can do with MySQL, in fact it wouldn’t allow me to do anything I couldn't do before but it expands my knowledge of MySQL which can only be of benefit.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113526071349024943?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113526071349024943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113526071349024943' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113526071349024943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113526071349024943'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/read-manual.html' title='Read the ******* Manual'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113525588204764144</id><published>2005-12-22T12:07:00.000Z</published><updated>2005-12-22T12:51:22.066Z</updated><title type='text'>A Warning about warnings.</title><content type='html'>Somebody recently asked a question about warnings in the MySQL Stored Procedure forum, the question its self was pretty easy but it raised another issue. &lt;br /&gt;&lt;br /&gt;The question was "How can I see warnings when MySQL reports them". The easy answer is to simply type "SHOW WARNINGS;" on the MySQL command line, however the show warnings command only shows the last error message, thats fine if you actually type "SHOW WARNINGS;" immediately after the statement that had the problem but if you make a mistake or wait for something else to go wrong then the warning message is removed and replaced by something else. &lt;br /&gt;&lt;br /&gt;The answer of course is not to make a mistake, but for people like me who come from a different background, in my case Oracle, the commands are different. I'm forever typing "SHO WARNINGS;" or "SHOW ERROR;" both of which result in another error and hence I lose the original message. &lt;br /&gt;&lt;br /&gt;But here's a tip I used when working with stored procedures with Oracle. Because of their nature I'd write stored procedures in a file and then load them using the @ command, this can be recreated in MySQL using the &lt;span style="font-weight:bold;"&gt;source&lt;/span&gt; command. I'd also, in the early days, make a lot of mistakes, well not alot but enough that I had to write the SHOW ERRORS command on a regular basis. Rather than type it each time I added the SHOW ERRORS command to all of my procedure creation scripts, if there was an error it was displayed and if there wasn't I'd get a rather good message simply saying No Errors.&lt;br /&gt;&lt;br /&gt;So my advice is if you're creating procedures or complex SQL just add a &lt;span style="font-weight:bold;"&gt;SHOW WARNINGS;&lt;/span&gt; command to the end of your script. Then you can just run the command from the script rather than the command line, if you do get any warnings they will display once the SQL has been run.... just don't make any mistakes writing show warnings in you file :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113525588204764144?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113525588204764144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113525588204764144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113525588204764144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113525588204764144'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/warning-about-warnings.html' title='A Warning about warnings.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113518676276060411</id><published>2005-12-21T17:06:00.000Z</published><updated>2005-12-21T17:39:22.796Z</updated><title type='text'>You get out what you put in.</title><content type='html'>I spend a fair amount of time on the MySQL forums and also over on the Quest Pipelines answering questions. I've mentioned on a few occasions about how I think this benefits me as much as the person asking questions, but one thing I've noticed a lot recently is the amount of, for the want of a better word, bad questions. &lt;br /&gt;&lt;br /&gt;In reality there are no bad or wrong questions, we all have to start somewhere, but what appears to be a problem is people only putting in the minimum of effort when asking, which often results in an equal amount of effort when people answer. Despite the rewarding nature of answering, a person is far more likely to help if they can answer the question easily or at least is given enough information to be able to answer fully. One of the problems with forums is that it doesn't lend its self to a conversational style, especially given the international nature of the web, I'm often dealing with questions from people around the world* where I'm answering one day and don't get a response until the next.&lt;br /&gt;&lt;br /&gt;So here are list of tips I'd give people wanting to ask questions on the various forums, so that you don't waste your time and people answering don't waste theirs.&lt;br /&gt;&lt;br /&gt;1. Be as descriptive as possible, context is all important. Often a solution can vary greatly on the context in which it will be used. I often see people simply asking how do I do X, this often gets the standard read the manual response. If you tailor the question people are much more likely to tailor the answer.&lt;br /&gt;&lt;br /&gt;2. When giving data structures and examples make sure it's all included. People often trim down their SQL examples to try and make it easier for people to answer, this often leads to relevant information being missed and an incorrect or less complete answer being given. I've often see perfectly good answers wasted by people responding that the solution doesn't work because they are using a join or something equally fundamental to how the SQL should be written. &lt;br /&gt;&lt;br /&gt;3. What’s slow? Many times people ask questions about slow running queries, but what's slow exactly. As fantastic as MySQL and Oracle are sometimes it's simply not possible to reduce long running SQL statements down to seconds. Somebody who works in a data warehousing environments definition of slow might be very different to someone working on a transactional system for example. &lt;br /&gt;&lt;br /&gt;4. Post it in the relevant place. Most forums have a category structure and often people will tend to answer in their area of expertise. The best possible chance of getting your question answered is to target these people. If your unsure there is normally a general area which is fine.&lt;br /&gt;&lt;br /&gt;This is just a short list and I'd welcome comments from others about what they would like to see. But above all give as much detail as possible, if its important enough to ask then its important enough to spend just a little extra time on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;* The nature of the web means that often people are asking questions in a second tounge. I do realise that this can be difficult but people are pretty forgiving of grammer and spelling if the question is well structured. Its also worth mentioning that the language you're writting in is not your first as often people who seem to speak English for example actually speak another language.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113518676276060411?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113518676276060411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113518676276060411' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113518676276060411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113518676276060411'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/you-get-out-what-you-put-in.html' title='You get out what you put in.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113516488716221481</id><published>2005-12-21T10:51:00.000Z</published><updated>2005-12-21T11:38:30.653Z</updated><title type='text'>Considering the Database</title><content type='html'>I've just started reading Pro MySQL by Jay Pipes and Michael Kruckenberg, Apress were kind enough to send me a free copy but what with the first copy going missing in the post and being busy it's only now I've had the chance to have more than a flick through. I have of course started with chapter one, Analyzing Business Requirements, you may be thinking why a book about MySQL starts with a chapter on a subject which is more related to application design, I don't think many people would have even noticed if it had been missing and the book kicked off with chapter two Index Concept. But this raises a really important point, and one which is often missed in the development process. The database is an essential part of most IT projects, it should be kept in mind from the very start. &lt;br /&gt;&lt;br /&gt;In my experience of projects I've worked on the database has often been an after thought. Take for example a recent project I worked on, it was a large e-commerce site built on Linux, PHP and Oracle. There was a very detailed specification with endless screen shots and mock-ups of the site design but the database design was nothing more than a simple schema diagram, apart from the odd line joining tables there was next to no information about how the database was going to function, what referential integrity was to be included, no information about indexes and having read the specification it was clear there were large parts of the database which hadn't been included. What was significant was the amount of effort which had gone into the look and feel of the site and in contrast the lack of time that had been spent on the database. &lt;br /&gt;&lt;br /&gt;As usual I came into the project at the coding stage, far too late to be able to spend time looking at the requirements and working out the impact on the database. The database evolved organically, the database schema was used to create the base tables but these changed on a daily if not hourly basis. I did my best to add the necessary referential integrity, add indexes where appropriate but as we were into the coding phase it was all a little bit of a fire fighting exercise. Despite the fact we had a detailed specification the nitty gritty of how some of the functionality was to be achieved was missing, the search functionality for example evolved over time and it became increasingly difficult to optimize the database to deal with this. &lt;br /&gt;&lt;br /&gt;Things came to a head when we started to stress test the site, anything over 20 concurrent users and the site crashed. We identified some bottlenecks which were addressed and this fixed the immediate problem. But when the site went live we had other problems related to periods of high usage. This meant periods of panic where we had to analyse the site and find the problems, often this involved big changes to the database which in some cases had a serious impact on the site. &lt;br /&gt;&lt;br /&gt;The site launch was a success and the performance problems we had didn't seem to cause a negative impact in terms of visitor numbers, but it would have been far better to have taken just a quarter of the time we took fixing problems retrospectively in designing the database in the first place and the subsequent problems we had could have been avoided.*&lt;br /&gt;&lt;br /&gt;So I'm more than happy that Jay and Michael decided to kick of Pro MySQL with "Analyzing Business Requirements". The moniker Pro seems more than justified.&lt;br /&gt;&lt;br /&gt;*&lt;span style="font-style:italic;"&gt;I should say I had a great time working on the project, the client was extremely happy with result and the project was well run.  I feel a little guilty about using it as an example but it was a classic case of where it could have been even more successful and stress free if time had been take to consider the database right from the very start.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113516488716221481?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113516488716221481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113516488716221481' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113516488716221481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113516488716221481'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/considering-database.html' title='Considering the Database'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113507039301996257</id><published>2005-12-20T08:59:00.000Z</published><updated>2005-12-20T09:19:53.066Z</updated><title type='text'>Delimiter Woes</title><content type='html'>Hands up who's had an error message when they have issued an SQL statement with ; delimiter straight after they created a procedure, or had an error when they tried to create a procedure without first setting the delimiter. 1..2..3.."is that a hand or are you trying to swat a fly".. I imagine it's a fair few of you, in fact I know it's a fair few because over the past year or so it's one of the biggest things people have asked me about or have had when trying to create procedures. Not why have they made a mistake but why MySQL needs you to change the delimiter when creating stored routines (SQL/PSM). &lt;br /&gt;&lt;br /&gt;When you think about it it's rather obvious, because lines are terminated with a semi-colon in SQL/PSM the MySQL command line client gets confused about what your trying to do. The delimiter needs to be changed so MySQL can tell the difference between straight SQL and SQL/PSM. &lt;br /&gt;&lt;br /&gt;So what's the problem? Well there are two things, firstly the MySQL Stored Procedure documentation mentions that you need to change the delimiter but only ever mentions //. This is a problem because the MySQL Query Browser (or at least the version I and others have been using) and some other interfaces don't like // as a delimiter, secondly a lot of people I have been in contact with are coming from other databases, in many cases Oracle and on Oracle you don't need to set the delimiter to something different. There is also the issue of people writing code examples that use other delimiters (which isn't a problem in it's self) and this again has caused confusion. &lt;br /&gt;&lt;br /&gt;With this in mind I have raised a feature request (#15880) asking if MySQL could deal with SQL/PSM without having to change the delimiter. I know it seems like a minor issue but it's the little things that often make all the difference.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113507039301996257?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113507039301996257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113507039301996257' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113507039301996257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113507039301996257'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/delimiter-woes.html' title='Delimiter Woes'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113500996805203826</id><published>2005-12-19T16:22:00.000Z</published><updated>2005-12-19T16:32:48.073Z</updated><title type='text'>MySQL Stored Procedure Programming (The Book)</title><content type='html'>On a recent visit to O'Reilly I noticed a list of up coming books. There were the usual second edition of this and third edition of that, but among those was a book that looks like it will become a classic. MySQL Stored Procedure Programming is being written by Steven Feuerstein and Guy Harrison, I'll admit to not knowing much about Guy but I'm fully aware of Steven. For those that don't know Steven he's possible the worlds number one expert on Oracle's PL/SQL, having written a number of books which are seen as the standard by which we should all aim for.&lt;br /&gt;&lt;br /&gt;I have all of Steven's Oracle books and if this MySQL book is even half as good as those it's going to be a great book. But it's not due for release until March 2006 and as we all know these things tend to have a habit of slipping a bit. But at $39.99 that at least gives us the time to save up the pocket money.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113500996805203826?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113500996805203826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113500996805203826' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113500996805203826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113500996805203826'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/mysql-stored-procedure-programming.html' title='MySQL Stored Procedure Programming (The Book)'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113474943966024579</id><published>2005-12-16T15:40:00.000Z</published><updated>2005-12-16T16:10:39.690Z</updated><title type='text'>Quest Pipelines</title><content type='html'>I've been an Oracle developer for around 8 years. For the first few years I was on my own, a PL/SQL book and Metalink was all I had to find my way in the Oracle darkness. As my experience grew the books became less of an aid and Metalink is often like looking for a needle in a haystack. So I had a look around at the various forums around, they were all much of a muchness, but one just seemed to be much more of a community than the rest. That was &lt;a href="http://www.quest-pipelines.com/pipelines/dba/index.asp"&gt;Quests Pipelines&lt;/a&gt;, what was great about it was that 1. people answered the questions quickly and 2. there were a lot of people answering. I've always found that you get just as much by answering questions than you do asking them, most of our time as developers is spent on mundane repetitive tasks or at least on stuff that doesn't push the boundaries of SQL too much. Maybe once or twice we need to do something a little more complex, something we haven't done before. But on a forum there are literally hundreds of people having these once or twice a year moments on a daily basis, by being involved in a forum you can tackle these sort of problems on a regular basis, his improves your skills by exposing you to things you might never have looked at.&lt;br /&gt;&lt;br /&gt;The reason I mention this is that &lt;a href="http://lenz.homelinux.org/blog/index.php?np_act=output_all#%3Cf7443aa8f9.20051216140921%40newsposter.webhop.org%3E"&gt;Lenz Grimmer&lt;/a&gt; mentioned the pipelines in his blog earlier today. In addition to the Oracle pipelines (one each for DBA's and Developers) there is also a MySQL Pipeline, the pipeline contains a forum, a regular monthly tip and articles. The MySQL pipeline has been open for about a year and I've been a sysop almost from the start, however visitor numbers have been low, I think that's in part to the great forums run by MySQL themselves. But I think there is room for more than one MySQL forum on the web so come on over and say high.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113474943966024579?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113474943966024579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113474943966024579' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113474943966024579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113474943966024579'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/quest-pipelines.html' title='Quest Pipelines'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113440003045254887</id><published>2005-12-12T14:55:00.000Z</published><updated>2005-12-12T15:07:10.480Z</updated><title type='text'>MySQL Connector/J</title><content type='html'>It seems I only ever post these days to shamelessly plug MySQLDevelopment.com :) However recently my conscience has been clear because I've actually been plugging content written by people rather than myself. &lt;br /&gt;&lt;br /&gt;Roland Bouman has done a great job on his blog recently (even winning the grand prize in the MySQL 5 competition), but he has still found time to kindly write content for MySQLDevelopment.com, this weekend we put the final touches to his introduction to the Call Level Interface and Connector/J articles. They are available now at the following URL&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mysql.gilfster.com/page.php?parent_id=3a&amp;page_id=3a.0.1"&gt;http://mysql.gilfster.com/page.php?parent_id=3a&amp;page_id=3a.0.1&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113440003045254887?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113440003045254887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113440003045254887' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113440003045254887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113440003045254887'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/mysql-connectorj.html' title='MySQL Connector/J'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113351428966160115</id><published>2005-12-02T08:47:00.000Z</published><updated>2005-12-02T09:04:49.676Z</updated><title type='text'>Another Week Off?</title><content type='html'>I've recently noticed my name dropping further and further down the most active list over at Planet Mysql. That's hardly a surprise given that I haven't added a blog in well over 2 weeks, but rather than just simply being too lazy this time I've had other excuses. &lt;br /&gt;&lt;br /&gt;First off I changed jobs, I was working on a short term contract which came to an end on 19th November, I had a week "off" (more on that in a second) and then started my new full time position this week. &lt;br /&gt;&lt;br /&gt;In my week "off" I spent most of the time working on www.mysqldevelopment.com, I've had a good response to my call for more help (we still want loads more) and people have been kind enough to donate ideas and content of their own for the site. That meant I was busy formating, updating and loading content for at least part of the week. People are also working on some great content based around the CLI and it's looking really good, it's something I've wanted to add to the site for some time but work pressures have played their part in slowing me down. &lt;br /&gt;&lt;br /&gt;Also congratulations to Roland, Markus and Beat on winning the MySQL 5.0 grand prize, as you all know they have produced some brilliant content on their blogs, along with plenty of work testing and bug reporting on the features of 5.0. But things should'nt stop there, the big push to get MySQL 5.0 released as been great but there is still a need for more info, more blogs and more bug reports to really push 5.0 forward.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113351428966160115?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113351428966160115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113351428966160115' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113351428966160115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113351428966160115'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/12/another-week-off.html' title='Another Week Off?'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113231819975205499</id><published>2005-11-18T12:28:00.000Z</published><updated>2005-11-18T12:53:24.980Z</updated><title type='text'>Formating Output of SQL</title><content type='html'>I mentioned a few posts ago about Oracle's SQL*Plus client program and how great it was at formatting output in different and novel ways, providing you know the commands to do it. One of the biggest problems is that the default linesize (the width of the screen buffer used to display rows of data in a table) is small and only actually displays something if you have small amount of columns. About 95% of the SQL I write breaks this  default and displays something which is totally unfathomable.&lt;br /&gt;&lt;br /&gt;The answer of course is to change the size of the linesize parameter, it's easily done and in fact with SQL*Plus you can set up a file to set this on log in, but I'm often connecting to servers where this file doesn't exist.&lt;br /&gt;&lt;br /&gt;Anyway getting to the point I found a nifty way to format data in MySQL into a more readable format, this isn't some great secret but I wasn't aware of it until recently. Let's take a normal SQL statement and result from the MySQL command line.&lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;mysql&gt; select * from emps where emp_id = 1;&lt;br /&gt;+--------+----------+---------+--------+--------+&lt;br /&gt;| emp_id | emp_name | dept_id | salary | bonus  |&lt;br /&gt;+--------+----------+---------+--------+--------+&lt;br /&gt;|      1 | Paul     |       1 | 100.00 | 100.00 |&lt;br /&gt;+--------+----------+---------+--------+--------+&lt;br /&gt;1 row in set (0.08 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;MySQL actually does a very good job of formatting the data in a readable format, but if we have a table with a large number of columns things get a little crowded, we have to keep scrolling left to right to see which data at one end relates to the other.&lt;br /&gt;&lt;br /&gt;But help is at hand, in MySQL you can format the returned results to be returned vertically rather than horizontally. This makes it easy to see data which is relevant to a single row only. To do this you simply append \G to the end of your select statement like so..&lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;mysql&gt; select * from emps where emp_id = 1\G&lt;br /&gt;****************** 1. row *****************  &lt;br /&gt;  emp_id: 1&lt;br /&gt;emp_name: Paul&lt;br /&gt; dept_id: 1&lt;br /&gt;  salary: 100.00&lt;br /&gt;   bonus: 100.00&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113231819975205499?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113231819975205499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113231819975205499' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113231819975205499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113231819975205499'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/11/formating-output-of-sql.html' title='Formating Output of SQL'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113214616826103835</id><published>2005-11-16T12:46:00.000Z</published><updated>2005-11-16T13:02:48.313Z</updated><title type='text'>Check Constraints in MySQL 5.0?</title><content type='html'>First let me point out MySQL doesn't support check constraints, I just wanted to point that out up front before you run off looking for them. When I was writing content on Triggers for my site &lt;a href="http://www.mysqldevelopment.com"&gt;www.mysqldevelopment.com&lt;/a&gt;, I was looking at ways to use triggers in the real world. People were asking me why they might want to use them. I came up with a few but one I mentioned just didn't seem to work. That was implementing check constraints via triggers. A check constraint is a constraint on a column in a table which limits what the column will accept, Oracle for example allows the use of check constraints when creating a table. MySQL itself has constraints such as primary key and unique but the features are very much limited to what MySQL wants you to do. A check constraint allows more flexibility, you can dictate what you want to allow in the column. &lt;br /&gt;&lt;br /&gt;For me it was obvious that triggers would be a great place to implement such a thing but the more I looked the less happy I was about implementing them. The first reason was that prior to 5.0.10 you couldn't access SQL from within a trigger. One of the things I would have needed to do was raise an error in the trigger to stop processing the insert/update, MySQL SQL/PSM doesn't currently allow you to raise an error manually, one way to do that would be to artificially raise one but because of the lack of support for SQL in triggers this wasn't possible without doing some potentially damaging things to the database. &lt;br /&gt;&lt;br /&gt;However come release 5.0.10 I still wasn't happy, the sort of error messages we could raise didn't relate to the actual error at all. So I gave up on the idea in the short term. &lt;br /&gt;&lt;br /&gt;But then I got an email from Scott Maxwell who came up with a suggestion on how this might be done. He's written a short article on the subject which can be seen here.... &lt;br /&gt;&lt;br /&gt;&lt;a href="http://mysql.gilfster.com/page.php?parent_id=2&amp;page_id=2.0.7"&gt;Emulating Check Constraints using Triggers.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113214616826103835?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113214616826103835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113214616826103835' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113214616826103835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113214616826103835'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/11/check-constraints-in-mysql-50.html' title='Check Constraints in MySQL 5.0?'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113163605664007851</id><published>2005-11-10T14:42:00.000Z</published><updated>2005-11-10T15:26:18.616Z</updated><title type='text'>Writing SQL Results to a File</title><content type='html'>Having been somewhat concerned with MySQL 5.0 in recent posts (and the iPod now being won :)), today I'm going to be going back to looking at some of the differences between MySQL and Oracle.&lt;br /&gt;&lt;br /&gt;Today it's the turn of output to a file from an SQL statement. Many of us old skool Oracle developers still prefer to use the good old SQL*Plus command line client, on of the reasons being that no matter where we are, be it on our desk top, on a clients site or even remotely via an ssh client we can be pretty sure a version is available. The great thing about SQL*Plus is that like the MySQL Command Line tool it's consistent across platforms, however one of the difficult things is that in it's standard mode you need to remember all manner of commands to get information to display the way you want.&lt;br /&gt;&lt;br /&gt;But the great thing about SQL*Plus is it's easy to save the results of your SQL to a file. All you need to do is issue the following command.&lt;br /&gt;&lt;pre style="color:red"&gt;&lt;br /&gt;SPOOL &lt;i&gt;location/filename&lt;/i&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;From then on any command issued in SQL*Plus is exported to that file. This is great but also at times rather annoying, for example the standard page size setting in SQL*Plus is 14, this means the column headers are reprinted after every 14 rows returned, the standard line size is also only 80 characters wide. It also displays the SQL command you used and a summary of the rows you returned.&lt;br /&gt;&lt;br /&gt;All these things are great when you need them but not so when you don't. SQL*Plus is very powerfull when it comes to reporting but most of the time my boss just wants a list of all the products which are out of stock, he doesn't care what the column name is (and certaily doesn't want it every 14 rows), he's not concerned with the SQL I used to get the data, and in many cases doesn't want to know how many rows it returned. So I then have to remember any number of SQL*Plus settings to suppress the information.&lt;br /&gt;&lt;br /&gt;To be honest I'm making a meal of it, it's not that hard. Once you have run your SQL and stored the results in the SPOOL file we then just issue the following command to tell SQL*Plus to stop sending output to the file.&lt;br /&gt;&lt;pre style="color:red"&gt;&lt;br /&gt;SPOOL OFF&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's all there is to it.&lt;br /&gt;&lt;br /&gt;So what about MySQL, well it's a lot easier to get what we want with MySQL than Oracle. We can embed our file output requirements right inside our SQL. This is done using the INTO OUTFILE command like so.&lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;mysql&gt; select emp_id, emp_name from emps &lt;br /&gt;       into outfile 'c:/test.txt';&lt;br /&gt;Query OK, 4 rows affected (0.03 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This simply produces the file without any fuss, each column output as is in the table.&lt;br /&gt;&lt;br /&gt;With SPOOL we can manipulate the file by simply formatting the output of the SQL, so if we wanted to output each column in the table with a comma delimiter we would have to concatenate the values together in the SQL to produce the required result. In MySQL there are a number of options we can use with INTO OUTFILE to change the way data is written to the file. These are FIELDS ESCAPED BY, FIELDS ENCLOSED BY, FIELDS TERMINATED BY and LINES TERMINATED BY. So if we wanted our output to be enclosed in double quotes, with comma delimiters and a new line termination for each row we would use...&lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;SELECT emp_id, emp_name &lt;br /&gt;INTO OUTFILE 'c:/result.text'&lt;br /&gt;FIELDS TERMINATED BY ','  ENCLOSED BY '"'&lt;br /&gt;LINES TERMINATED BY '\n'&lt;br /&gt;FROM emps;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This would produce the following file.&lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;"0","Barry"&lt;br /&gt;"1","Paul"&lt;br /&gt;"2","John"&lt;br /&gt;"3","Alan"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are of course some advantages to both, you can't for example continue to output to the same file across multiple results when using INTO OUTFILE, which you can using spool, but when using INTO OUTFILE you can concentrate on what you want selected and let MySQL deal with the formatting of the output rather than having to write it long hand when using SPOOL.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:red"&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/span&gt; The MySQL documentation shows the INTO OUTFILE as coming after the column list and before the table clause (as with SELECT INTO when using SQL/PSM) but it seems to work just as well if you have it after the from clause as I did in my first example.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113163605664007851?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113163605664007851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113163605664007851' title='62 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113163605664007851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113163605664007851'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/11/writing-sql-results-to-file.html' title='Writing SQL Results to a File'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>62</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113093572783318914</id><published>2005-11-02T12:09:00.000Z</published><updated>2005-11-02T12:48:47.853Z</updated><title type='text'>What hope for MySQL 5.0 Hosting</title><content type='html'>One of the great things about MySQL is its support from web hosting companies, many people use MySQL as a backend database for their websites, there are literally hundreds of web hosting companies offering MySQL and PHP and there are dozens of PHP/MySQL books on the market. &lt;br /&gt;&lt;br /&gt;I've written a fair amount about the new features of MySQL 5.0 and in particular Stored Procedures and Views. But there's nothing worse than people telling you to do one thing and doing another themselves. My site www.mysqldevelopment.com runs on PHP 4 and MySQL 4.0, simply because that's what my hosting company offers, they are cheap and offer a great service. I recently asked them what their plans were for upgrading accounts to MySQL 5.0, given that they are still on 4.0 I didn't hold out much hope. I was right they don't have any plans to upgrade in the short or medium term and given they didn't even know MySQL 5.0 was about to be released I wouldn't expect much to happen in the long term either. &lt;br /&gt;&lt;br /&gt;I'm about to start a new project, a simple site for me and a few friends and I thought it would be a great way to use 5.0 and also to include my observations in this very blog. But where could I get 5.0 hosting, I looked around the web and found nothing, well nothing apart from people offering to build be a server just the way I wanted and to be honest this site isn't anywhere near important enough for me to spend any money on it.&lt;br /&gt;&lt;br /&gt;Then I hit apon an idea, you may already be aware of db4free.net, they offer access to MySQL 5.0 which is hosted on their server, it's not web hosting but it's possible to remotely connect and therefore use your existing host to serve the pages. &lt;br /&gt;&lt;br /&gt;So all I need to do is use my hosting account to serve the PHP but connect remotely to my account on db4free.net..... &lt;br /&gt;&lt;br /&gt;... but alas even that doesn't work, because to connect to MySQL 5.0, as least to use stored procedures you need to use the MySQLi extensions, these need to be compiled specifically under PHP4. &lt;br /&gt;&lt;br /&gt;I suppose it's back to do as I say and not do as I do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113093572783318914?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113093572783318914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113093572783318914' title='20 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113093572783318914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113093572783318914'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/11/what-hope-for-mysql-50-hosting.html' title='What hope for MySQL 5.0 Hosting'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>20</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113076859340550513</id><published>2005-10-31T14:10:00.000Z</published><updated>2005-10-31T14:24:24.793Z</updated><title type='text'>Oracle Database XE</title><content type='html'>Latest news from the Oracle world is that they have just released a new beta version of their database product, Oracle 10g Express Edition (Oracle Database XE). What's so special about this release? Well it's free, Oracle have offered their databases for download for free to developers for as long as I can remeber but the important difference with XE is that you can use it in production environments without any charge also. This seems in direct competition with the current "free" databases on the market such as MySQL. &lt;br /&gt;&lt;br /&gt;The database is limited in that it can only be installed on single processor machines with 4Gb of disk memory and 1Gb of RAM. Andrew Mendelsohn, senior vice president of Oracle's server technologies division has said &lt;br /&gt;&lt;br /&gt;"There is definitely a market there (for low-end databases) and a demand. And we want them to be using Oracle and not MySQL or SQL Server Express" &lt;br /&gt;&lt;br /&gt;The theory is that students will be able use XE for free which will hopefully lead them on to the full Oracle database products. I suppose the question is, is it all a little too late, MySQL already has a great reputation in the area Oracle are targeting and IBM has, and Microsoft are, looking to release free lite versions of their  database offerings, DB2 Express and SQL Server Express.&lt;br /&gt;&lt;br /&gt;Versions for Windows and Linux are available for download from the Oracle website&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.oracle.com"&gt;http://www.oracle.com&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113076859340550513?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113076859340550513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113076859340550513' title='52 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113076859340550513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113076859340550513'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/oracle-database-xe.html' title='Oracle Database XE'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>52</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113023793082281175</id><published>2005-10-25T09:58:00.000Z</published><updated>2005-10-25T11:00:12.496Z</updated><title type='text'>Where did my comments go?</title><content type='html'>Following on from post about the MySQL forums, I answered a question this morning which might be of use to others. It relates to comments in MySQL Stored Routines (SQL/PSM). &lt;br /&gt;&lt;br /&gt;I suppose a quick mention of how to write comments in SQL/PSM would be usefull. There are two types of comments in SQL/PSM firstly there is a comment characteristic value we can use to store general comments about the routine, we will look at that later, then there are in-line comments, thesw will be similar to comments you may have used in other procedural languages or programming in general. &lt;br /&gt;&lt;br /&gt;The first is a single line comment, when ever you wish to simply show a single line comment you can use the following syntax &lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;-- This is a comment. &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;MySQL will ignore anything after the -- when it compiles the SQL/PSM code. The second type of in-line comment is the /* combination. This can be used to make comments on multiple lines of code like so. &lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;/* This is the first line of the commnet &lt;br /&gt;   and this the second line. */&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;MySQL will ignore any text between the /* and */, you must make sure that if you use multiple line comments that a closing */ is present. It's up to you which style you use, personally I tend to use -- as it's a habit I picked up years ago, I also tend to add ++ after the first comment character to denote the start of a section of comments, but thats very much a style choice on my point and doesn't offer anything interms of compilation. &lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt; --++ This is the first line of the commnet &lt;br /&gt; --   and this the second line&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;OK so we know how to write comments in SQL/PSM now on to the problem. Let's create a very simple SQL/PSM procedure. &lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;create procedure CommentTest() &lt;br /&gt;begin &lt;br /&gt;   -- this is a comment&lt;br /&gt;   select 'Comment Test';&lt;br /&gt;end;&lt;br /&gt;//&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now here comes the issue, we can issue a command to view the SQL/PSM code stored in the database like so. &lt;br /&gt;&lt;pre style="color:orange;"&gt;&lt;br /&gt;mysql&gt; show create procedure commenttest//&lt;br /&gt;+-------------+------------------------------------+&lt;br /&gt;| Procedure   | Create Procedure                   |&lt;br /&gt;+-------------+------------------------------------+&lt;br /&gt;| commenttest | CREATE PROCEDURE `commenttest`()   |&lt;br /&gt;|             | begin                              |&lt;br /&gt;|             |                                    |&lt;br /&gt;|             |   select 'Comment Test';           |&lt;br /&gt;|             | end                                |&lt;br /&gt;+-------------+------------------------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The SQL/PSM code is shown but there are no comments, this can also be seen if you are&lt;br /&gt;using the MySQL Administrator, when you click the "Edit Stored Proc" button the code is shown, but no comments are displayed. &lt;br /&gt;&lt;br /&gt;Where have they gone? well mysql removes any inline comments when the procedure is loaded into the database. This isn't such a problem for somebody like me who creates scripts to create procedures as I have the comments retained in the script, but if you create your procedures in something like MySQL administrator then those comments will be gone for good. &lt;br /&gt;&lt;br /&gt;Unfortunatley there isn't anything that can be done about this at present. The comments have passed on! They are no more! They have ceased to be! they have expired and gone to meet 'their maker! Bereft of life, they rest in peace! their metabolic processes are now 'istory! off the twig! they kicked the bucket, they shuffled off 'their mortal coil, run down the curtain and joined the bleedin' choir invisibile!! THEY ARE EX-COMMENTs!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113023793082281175?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113023793082281175/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113023793082281175' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113023793082281175'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113023793082281175'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/where-did-my-comments-go.html' title='Where did my comments go?'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113023420280725657</id><published>2005-10-25T09:39:00.000Z</published><updated>2005-10-25T09:56:42.813Z</updated><title type='text'>The MySQL Forum</title><content type='html'>Every now and again I browse the MySQL forums, it's a great way to help others, hone your own skills and also to learn something new. It's also a great inspiration for this blog, many of the topics I mention are directly related to message I see posted. I don't refer to messages directly as I wouldn't want to point out peoples mistakes publicly, which is often the reason behind a blog entry, I see a lot of the same sort of problems or assumptions and so write about it here to try and spread the knowledge around a bit.  &lt;br /&gt;&lt;br /&gt;Making mistakes or assumptions is never something to be ashamed of, as you well know I make them all the time, it's obvious people are coming to MySQL from other databases and trying to do things the same way they have in the past. Rather than worry about them we should embrace them, use them as a method for learning. The hard part comes in actually asking for help, it can often be a little difficult asking other people to look at your code, we want people to help with the immediate problem but we don't want to expose our code to the eyes of others.&lt;br /&gt;&lt;br /&gt;But if you do need help with a MySQL related problem, be it installation, simply SQL or stored procedures do checkout the MySQL forums, http://forums.mysql.com/. But don't let that be your only reason for visiting, get involved, have a go at answering  questions yourself.&lt;br /&gt;&lt;br /&gt;I for example know a fair amount about stored procedures but I know very little about performance issues. So I visit the performance forum from time to time to see the sort of thing people are asking about, this gives me a chance to look at things I might never have seen before.&lt;br /&gt;&lt;br /&gt;So give it a go, get involved.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113023420280725657?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113023420280725657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113023420280725657' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113023420280725657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113023420280725657'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/mysql-forum.html' title='The MySQL Forum'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113022711349007626</id><published>2005-10-25T07:36:00.000Z</published><updated>2005-10-25T07:58:33.496Z</updated><title type='text'>Finding (another) name for MySQL Stored Procedures</title><content type='html'>If you checked my blog yesterday you may have seen a post titled "Finding a name for MySQL Stored Procedures". The general theme was trying to find a smaller and more snappy method of refering to stored procedures within MySQL. I got a fair few comments from people about the blog which were generally positive and welcomed the idea. &lt;br /&gt;&lt;br /&gt;However, I recieved an email from MySQL AB requesting that we didn't use the name I had decided apon. The reason begin that it included a My prefix and MySQL AB feel that doing so dilutes the trademark. This can be seen in action for example in the renaming of MyODBC to Connector/ODBC. &lt;br /&gt;&lt;br /&gt;I of course don't have a problem with this, the intention of giving stored procedures a name was more to do with keeping things short and also removing the ambiguity of the word procedure when actually talking about functions. &lt;br /&gt;&lt;br /&gt;The big question is do MySQL stored procedures actually need a name? They conform to the ANSI Standards, or at least a subset of it, so perhaps when refering to stored procedures we can use the ANSI title of SQL/PSM (Persistant Stored Modules).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113022711349007626?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113022711349007626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113022711349007626' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113022711349007626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113022711349007626'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/finding-another-name-for-mysql-stored.html' title='Finding (another) name for MySQL Stored Procedures'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-113014191806977057</id><published>2005-10-24T07:55:00.000Z</published><updated>2005-10-25T07:59:55.140Z</updated><title type='text'>A MySQL Mantra</title><content type='html'>Having been in a previous incarnation an Oracle developer I kept a close eye on a site called AskTom. The Tom of AskTom is Tom Kyte who is an Oracle employee with a great passion for helping people with their Oracle problems. He's also an author of some great Oracle books which I recommned anybody developing with Oracle either directly via PL/SQL or with Oracle as the backend database read before they type a single line of code. &lt;br /&gt;&lt;br /&gt;Tom has a mantra with regard to developing with Oracle. It goes like this.&lt;br /&gt;&lt;br /&gt;o if you can do it in a single sql statement - do so.&lt;br /&gt;o if you cannot, do it in as little PLSQL as you can.&lt;br /&gt;o if you cannot, because plsql cannot do it, try some java (eg: sending an email &lt;br /&gt;with an attachment)&lt;br /&gt;o if you cannot do it in java (too slow, or you have some existing 3gl code &lt;br /&gt;already) do it in C as an extproc.&lt;br /&gt;&lt;br /&gt;This is great advice, at least for Oracle developers, in that it's making the most of each method at the appropriate stage. An SQL statement for example is far superior for data manipulation than say PL/SQL because Oracle has been built from the ground up to be as fast as possible when using SQL. But it's also true that the feature set is limited when it comes to decision making, this means there are often times when you need to revert to PL/SQL to get the job done. The third stage is somewhat particular to Oracle in that it has a JVM built into the database, therefore you can call Java as you would a stored procedure and execute this right inside the database. &lt;br /&gt;&lt;br /&gt;One thing to be clear on here is we are not talking about developing whole applications in Oracle, we are talking about manipulating data, this means that we really won't be getting much passed stage 2 in 99% of the situations we might come across. The only time we might need to move on to the Java stage is if we need to interact with the outside world, Tom's email example being the obvious case (having said that in Oracle there are PL/SQL packages available to send email). &lt;br /&gt;&lt;br /&gt;So how does this tie in with MySQL, it got me thinking about what a suitable Mantra would be for MySQL. I've come up with the following, based very much on Tom's Oracle Mantra, but it's by no means something set in stone, I'd really appreciate feedback on what people think.&lt;br /&gt;&lt;br /&gt;o if you can do it in a single sql statement - do so.&lt;br /&gt;o if you cannot, do it in as small a stored procedure as you can.&lt;br /&gt;o if you cannot, because a stored procedure cannot do it, try a UDF&lt;br /&gt;o if you cannot, because a UDF isn't suitable take the code out of the database&lt;br /&gt;&lt;br /&gt;I should say with regard to the last stage it's likely that if you have exhausted the first three stages then you're most likely no longer dealing with data exclusively and therefore the code may live more comfortably in your application layer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-113014191806977057?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/113014191806977057/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=113014191806977057' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113014191806977057'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/113014191806977057'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/mysql-mantra.html' title='A MySQL Mantra'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112976015069082077</id><published>2005-10-19T22:00:00.000Z</published><updated>2005-10-25T08:22:04.116Z</updated><title type='text'>MySQL 5.0 Stored Procedures : Part 4 (update)</title><content type='html'>As long ago as last week I said that on the following day I'd post a new blog entry on Stored Procedures, yet again the day job has beaten me. It's now a week later and I still haven't found a spare 20-30 minutes to devote enough time to write the next instalment. &lt;br /&gt;&lt;br /&gt;So as way of an update I'll just briefly go over the homework I set. I asked "what happens if you don't use INTO to pass the value into a variable", I gave a clue or at least mentioned that in Oracle trying to load a procedure with a select statement without an into clause results in a compile error (PLS-00428 to be exact). &lt;br /&gt;&lt;br /&gt;But MySQL exhibits some interesting behaviour, I'm not exactly sure if it's by design but when issuing a 'normal' select statement in a procedure rather than an error MySQL returns the result set as if you have issued the command directly from the command line.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112976015069082077?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112976015069082077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112976015069082077' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112976015069082077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112976015069082077'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/mysql-50-stored-procedures-part-4_19.html' title='MySQL 5.0 Stored Procedures : Part 4 (update)'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112975895412827289</id><published>2005-10-19T21:50:00.000Z</published><updated>2005-10-19T21:56:13.693Z</updated><title type='text'>IE Problems</title><content type='html'>It's seems as if this blog was having problems displaying correctly in IE, thanks to Roland for pointing that out. It was to do with the code samples and my use of &amp;lt;pre&amp;gt; to format them in a consistent way. &lt;br /&gt;&lt;br /&gt;As a Mac user I tend to write this blog using Safari and when I view from work it's done via FireFox so the problems didn't show up for me. In future I'll test on IE just to make sure everythings OK, a new layout may be in order to address the problem going forward.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112975895412827289?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112975895412827289/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112975895412827289' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112975895412827289'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112975895412827289'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/ie-problems.html' title='IE Problems'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112911598147755852</id><published>2005-10-12T11:09:00.000Z</published><updated>2005-10-19T21:48:23.283Z</updated><title type='text'>MySQL 5.0 Stored Procedures : Part 4</title><content type='html'>OK, it's been nearly 2 weeks since the last item on stored procedures, so sorry to those who had been following along, I'm sure by this point you will have gone elsewhere for your Stored Procedure fix, but I'll pickup where I stopped with Part 3. &lt;br /&gt;&lt;br /&gt;Today we will be looking at selecting records within a stored procedure. I'm sure if you looking at MySQL 5.0.13 you may have been using MySQL 4 for sometime or at least have some experince of writing SQL statements with other database technologies. Therefore I'll assume you know what one looks like and how to construct one using your database tables.&lt;br /&gt;&lt;br /&gt;I'll be using a table called emps in this example.. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; desc emps;&lt;br /&gt;+----------+---------------+------+-----+---------+&lt;br /&gt;| Field    | Type          | Null | Key | Default |&lt;br /&gt;+----------+---------------+------+-----+---------+&lt;br /&gt;| emp_id   | int(11)       | NO   | PRI |         |&lt;br /&gt;| emp_name | varchar(30)   | YES  |     | NULL    |&lt;br /&gt;| dept_id  | int(11)       | YES  |     | NULL    |&lt;br /&gt;| salary   | decimal(5,2)  | YES  |     | NULL    |&lt;br /&gt;| bonus    | decimal(12,2) | YES  |     | NULL    |&lt;br /&gt;+----------+---------------+------+-----+---------+&lt;br /&gt;5 rows in set (1.72 sec)&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;In pervious procedure examples we used a parameter to pass in a name to include in our output string, what might be more usefully from an application persepctive is to be able to pass in an employee's ID number (in our example table this is the emp_id column) and then display the associated employee's name. &lt;br /&gt;&lt;br /&gt;So how do we do that in a procedure, in a normal command line environment we would just issue a select statement as follows&lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; select emp_name from emps where emp_id = 1;&lt;br /&gt;+----------+&lt;br /&gt;| emp_name |&lt;br /&gt;+----------+&lt;br /&gt;| Paul     |&lt;br /&gt;+----------+&lt;br /&gt;1 row in set (0.14 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But in our procedure we want to use the name as part of our output string, to do this we need to use &lt;span style="font-weight:bold;"&gt;INTO&lt;/span&gt; in our select statement. INTO passes the value of the select into a variable, "Hold on" you say "what's all this variable buisness?". In general and simplistic terms a variable is a data store, a named area of memory we can use to hold values during the execution of a procedure&lt;br /&gt;&lt;br /&gt;You can find more information on variables here...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mysql.gilfster.com/page.php?parent_id=1.1&amp;page_id=1.1.5"&gt;http://mysql.gilfster.com/page.php?parent_id=1.1&amp;page_id=1.1.5&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To keep things short I'll let you look into variables if you need to, but I'll press on. So the first thing we need to do is create the variable, then we issue the select statement passing the output into the variable using INTO, then we reference the variable in much the same way as we referenced the parameter in previous examples. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; delimiter //&lt;br /&gt;mysql&gt; create procedure &lt;br /&gt;    -&gt; hello_employee(IN p_emp_id INT)&lt;br /&gt;    -&gt; begin&lt;br /&gt;    -&gt; declare p_name varchar(30);&lt;br /&gt;    -&gt; select emp_name into p_name from emps &lt;br /&gt;    -&gt; where emp_id = p_emp_id;&lt;br /&gt;    -&gt; select concat('Hello ',p_name);&lt;br /&gt;    -&gt; end;&lt;br /&gt;    -&gt; //&lt;br /&gt;Query OK, 0 rows affected (0.30 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; call hello_employee(1)//&lt;br /&gt;+-------------------------+&lt;br /&gt;| concat('Hello ',p_name) |&lt;br /&gt;+-------------------------+&lt;br /&gt;| Hello Paul              |&lt;br /&gt;+-------------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;Great, so we can now see how to select values from a table in our procedures. &lt;br /&gt;Have a go at constructing your own select statements, any select statement that's valid on the command line is valid in a procedure. &lt;br /&gt;&lt;br /&gt;For homework, what happens if you don't use INTO to pass the value into a variable. Those of you who have worked with another procedural language such as Oracle's PL/SQL might expect it to fail, in fact not even compile, what happens in MySQL? I'll discuss what happens and the implications of this tomorrow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112911598147755852?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112911598147755852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112911598147755852' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112911598147755852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112911598147755852'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/mysql-50-stored-procedures-part-4.html' title='MySQL 5.0 Stored Procedures : Part 4'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112903606387437017</id><published>2005-10-11T12:53:00.000Z</published><updated>2005-10-11T13:07:43.880Z</updated><title type='text'>Wow...</title><content type='html'>I got back from my vacation at 7:00 am UK time yesterday, I had a quick shower and it was straight back to work, things are busy here in the office as we just went live on a rather large ecommerce site, it's looking great so far no major problems but plenty of little things to keep us all busy over the first few weeks I'm sure.&lt;br /&gt;&lt;br /&gt;All of this meant that I didn't have a chance to catch up with my personal email until I got home last night. I logged on expecting the odd email (I don't get many to that address) but I had loads. But of course the important one was the email from Arjen Lentz telling me I'd won an iPod Nano for my work on this blog and also over at &lt;a href="http://www.mysqldevelopment.com"&gt;www.mysqldevelopment.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I was both surprised and honored to be receiving the first weeks prize, it real was unexpected. When I started the short series on using stored procedures a few weeks a go there was a genuine desire on my part to impart at least a little knowledge to people reading this blog so they could go off and start trying to find those bugs, write blogs and win those iPods.&lt;br /&gt;&lt;br /&gt;So thanks to MySQL, Arjen and everybody who's been following this blog or the site. There are still 7 (soon to be 6) iPods up for grabs and also those 3 Grand Prize of a pass to the 2006 MySQL Users Conference, so keep blogging and looking for those bugs.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/mysql_5_contest.html"&gt;http://dev.mysql.com/mysql_5_contest.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112903606387437017?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112903606387437017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112903606387437017' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112903606387437017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112903606387437017'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/wow.html' title='Wow...'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112895311733208322</id><published>2005-10-10T13:59:00.000Z</published><updated>2005-10-10T14:05:17.343Z</updated><title type='text'>Sorry</title><content type='html'>I seem to spend every few blogs issuing an apology. This week I'm saying sorry for not keeping you guys posted with regards to my absence over the last week. I'd got off to a good start with the blog entries for getting started with Stored Procedures and then I realised I had other commitments coming up fast, first a client going live at the weekend and secondly a weeks holiday in Jamaica.&lt;br /&gt;&lt;br /&gt;Well both were a great success, I left the go live in the very capable hands of my work colleagues, but took the holiday myself. The Hotel had an internet room but I resisted the temptation and went the whole week without using a computer.&lt;br /&gt;&lt;br /&gt;So if you have been checking back for an update to the stored procedure items, I'll be back on those very soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112895311733208322?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112895311733208322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112895311733208322' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112895311733208322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112895311733208322'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/10/sorry.html' title='Sorry'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112807722655362417</id><published>2005-09-30T10:26:00.000Z</published><updated>2005-10-19T21:50:20.963Z</updated><title type='text'>MySQL 5.0 Stored Procedures : Part 3</title><content type='html'>SO far we have looked at creating a simple procedure, then we added a couple of more lines to make it into a multiline procedure, but after all that our procedure is still a little useless. So let's look at how to make it a little more dynamic by passing in a value (or values) via a parameter. &lt;br /&gt;&lt;br /&gt;Again I'll keep things simple, if you want to know more about parameters in programming in general pretty much any book on the subject of programming will have some sort of explanation so I'll leave you to do the research on that. But in essence parameters allow us to pass information in (and in the case of procedures, out) of our stored routines. "Hey, hold on" you all say.... "What's all this routine buisness". I suppose now is as good a time as any to introduce the word routine, so far we have been using the term "Stored Procedure" to mean program elements stored permanently in MySQL. But it's possible to use both functions and procedures, therefore it's good to have a term which covers both and make a distinction when talking explicitly about a procdure rather than routines in general. &lt;br /&gt;&lt;br /&gt;...anyway back to parameters. So let's take our "hello world" example a stage further , lets say we wanted to say hello to anybody we chose. We could of course create a procedure for all our users, but a much better solution would be to pass in the name of the person we want to say hello to. I glossed over the () placed at the end of the procedure name in the first part, but it's this that we use to pass the parameters in and out of our routine. By default parameters are classed as IN parameters, this means the procedure will accept values into them, but we can also define them as OUT or even INOUT. &lt;br /&gt;&lt;br /&gt;All we need to do is give the parameter a name and a datatype, the datatype can be any valid MySQL datatype that you would use for a column datatype in a table. Once it's defined we can then reference the parameter in our procedure using it's name. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; delimiter //&lt;br /&gt;mysql&gt; create procedure &lt;br /&gt;    -&gt; testParam(p_name varchar(30))&lt;br /&gt;    -&gt; begin&lt;br /&gt;    -&gt;    select concat('Hello ',p_name);&lt;br /&gt;    -&gt; end&lt;br /&gt;    -&gt; //&lt;br /&gt;Query OK, 0 rows affected (0.06 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; call testParam('Bob')//&lt;br /&gt;+-------------------------+&lt;br /&gt;| concat('Hello ',p_name) |&lt;br /&gt;+-------------------------+&lt;br /&gt;| Hello Bob               |&lt;br /&gt;+-------------------------+&lt;br /&gt;1 row in set (0.01 sec)&lt;br /&gt;&lt;br /&gt;Query OK, 0 rows affected (0.01 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's all there is to it. We can now just call the procedure using any name we like. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; call testParam('Sue')//&lt;br /&gt;+-------------------------+&lt;br /&gt;| concat('Hello ',p_name) |&lt;br /&gt;+-------------------------+&lt;br /&gt;| Hello Sue               |&lt;br /&gt;+-------------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;/pre&gt; &lt;br /&gt;OK, now for your home work.... This page has information on the different types of parameters.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://mysql.gilfster.com/page.php?parent_id=1.1&amp;page_id=1.1.6"&gt;http://mysql.gilfster.com/page.php?parent_id=1.1&amp;page_id=1.1.6&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the next blog entry I'll be looking at interacting with the database using SQL inside the procedure. I promise that this is going somewhere usefull :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112807722655362417?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112807722655362417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112807722655362417' title='98 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112807722655362417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112807722655362417'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/09/mysql-50-stored-procedures-part-3.html' title='MySQL 5.0 Stored Procedures : Part 3'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>98</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112798693381254155</id><published>2005-09-29T09:30:00.000Z</published><updated>2005-09-29T13:07:29.180Z</updated><title type='text'>MySQL 5.0 Stored Procedures : Part 2</title><content type='html'>In theb last blog entry I looked at how to create a very simple stored procedure. While it demonstrated how quick and easy it was to create a stored procedure it wasn't particuarly usefull. &lt;br /&gt;&lt;br /&gt;So today I'll be showing you two additional things (spread over two entries), you can do to expand on yesterdays example. First up it's creating a multiline procedure. On first consideration this might not seem to be something you need to deal with, why can't you just keep adding lines to the procedure. The problem with that is that MySQL needs to firstly know where the procedure code starts and ends (in our first example it wasn't a problem because it was a single line of code) and also it needs to know when a particular command ends. &lt;br /&gt;&lt;br /&gt;Take for example the MySQL command line tool, when you enter an SQL statement you need to add a semicolon ; to the end of the SQL command to tell MySQL that there is no more to enter and to begin processing the command. This is the same for stored procedures, you need to tell MySQL where the individual commands in the procedure end. However MySQL uses the same line delimiter for stored procedures as it does for normal command line operations, this means that when entering multiline procedures we need to change the default delimiter character. Doing this is trivial but it does mean you have to get yourself into "different delimiter mode" in that if your anything like me you will be constantly wondering why MySQL hasn't processed that select. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; delimiter //&lt;/pre&gt;&lt;br /&gt;Personally I use the // as the new delimiter, your free to choose one you prefer but // seems to work well and not clash with MySQL. So how does this effect MySQL, where we would have used ; we now need to use the new delimiter. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; select 'Test of Delimiter'//&lt;br /&gt;+-------------------+&lt;br /&gt;| Test of Delimiter |&lt;br /&gt;+-------------------+&lt;br /&gt;| Test of Delimiter |&lt;br /&gt;+-------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;/pre&gt;&lt;br /&gt;So now the question is how does this relate to stored procedures. Let's create a similar procedure to our last, this time rather than using a literal in the select we can first set a user variable and then select that. The second thing we need to do when creating multiline stored procedures is enclose the body of the procedure (the actual code but not the head) within a begin and an end block. So it looks like this...&lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; create procedure testProc()&lt;br /&gt;    -&gt; begin&lt;br /&gt;    -&gt; set @a = 'HelloWorld';&lt;br /&gt;    -&gt; select @a;&lt;br /&gt;    -&gt; end;&lt;br /&gt;    -&gt; //&lt;br /&gt;Query OK, 0 rows affected (0.28 sec)&lt;/pre&gt;&lt;br /&gt;You can see that the two lines are enclosed within the begin and end and that each one is terminated with the ; delimiter. Because we have changed the MySQL command line default delimiter to get MySQL to process the create procedure statement we need to enter the new delimiter after the procedure statement. &lt;br /&gt;&lt;br /&gt;So to run the procedure we just call it as we did with our first example.&lt;br /&gt;&lt;pre style="color:orange"&gt; &lt;br /&gt;mysql&gt; call testProc()//&lt;br /&gt;+------------+&lt;br /&gt;| @a         |&lt;br /&gt;+------------+&lt;br /&gt;| HelloWorld |&lt;br /&gt;+------------+&lt;br /&gt;1 row in set (0.01 sec)&lt;br /&gt;&lt;br /&gt;Query OK, 0 rows affected (0.01 sec)&lt;/pre&gt;&lt;br /&gt;Great we have created a multiline procedure, but it still doesn't do a great deal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112798693381254155?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112798693381254155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112798693381254155' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112798693381254155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112798693381254155'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/09/mysql-50-stored-procedures-part-2.html' title='MySQL 5.0 Stored Procedures : Part 2'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112782315794171739</id><published>2005-09-27T11:34:00.000Z</published><updated>2005-10-19T21:49:21.746Z</updated><title type='text'>MySQL 5.0 Stored Procedures : Getting Started</title><content type='html'>In response to MySQL's call to arms (or should that be call to keyboards) with regard to MySQL 5.0 going to the RC stage, over the next few days I'll be giving you a brief introduction to Stored Procedures within MySQL. Hopefully this should give you enough of a heads up to start seriously testing this new aspect of MySQL.&lt;br /&gt;&lt;br /&gt;Stage one of course is to download and install the lastest version of MySQL, that's currently 5.0.13 and is available here &lt;a href="http://dev.mysql.com/downloads/mysql/5.0.html"&gt;http://dev.mysql.com/downloads/mysql/5.0.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;OK, once you're all installed let's start up a MySQL command line session and select a database to develop against. Let's keep it really simple to start with, I won't go into too much detail during these tutorials, if you need more info I'll point you in the right direction at the end. &lt;br /&gt;&lt;br /&gt;To start we will use the ubiquitous HelloWorld program to simply display some text on the MySQL command line. To do this all we need to do is call a select statment. To create a procedure we just need to type the keywords &lt;span style="font-weight:bold;"&gt;CREATE PROCEDURE&lt;/span&gt; give the procedure a name, add a set of brackets (more on those tomorrow) and then enter our select command.&lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; create procedure helloword() &lt;br /&gt;     -&gt; select 'Hello World';&lt;br /&gt;Query OK, 0 rows affected (0.30 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Great, we can tell by the message that the procedure was created (there were no errors or warnings reported). All we need to do now is run our procedure, this is just as simple as writing it in the first place. Just type &lt;span style="font-weight:bold;"&gt;CALL&lt;/span&gt;, then our procedure name followed by those brackets again. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; call helloword();&lt;br /&gt;+-------------+&lt;br /&gt;| Hello World |&lt;br /&gt;+-------------+&lt;br /&gt;| Hello World |&lt;br /&gt;+-------------+&lt;br /&gt;1 row in set (0.02 sec)&lt;br /&gt;&lt;br /&gt;Query OK, 0 rows affected (0.02 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Congratulations thats your first MySQL Stored Procedure. You may be saying to yourself that we haven't done anything you could have done straight from the command line (and you would be correct), but the thing with stored procedures is we can run the same thing again and again and agian.... and so on. I'll explain more about why thats good later but just to test the theory try and run the procedure again. &lt;br /&gt;&lt;br /&gt;OK before you get a call from your MySQL DBA I better tell you how to remove your procedure. It's just as easy to get rid of one as it is to create one. &lt;br /&gt;&lt;pre style="color:orange"&gt;mysql&gt; drop procedure helloword;&lt;br /&gt;Query OK, 0 rows affected (0.20 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Thats all there is to it. Next time we will look at creating a procedure which has more than one line of code and how to pass values into our procedure and adapt the output accordningly.&lt;br /&gt;&lt;br /&gt;If you keen to learn more and don't want to wait for the next installment check out the following resources. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://mysql.gilfster.com/"&gt;http://www.mysqldevelopment.com&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/doc/mysql/en/stored-procedures.html"&gt;http://dev.mysql.com/doc/mysql/en/stored-procedures.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/tech-resources/articles/mysql-storedprocedures.html"&gt;http://dev.mysql.com/tech-resources/articles/mysql-storedprocedures.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112782315794171739?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112782315794171739/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112782315794171739' title='73 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112782315794171739'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112782315794171739'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/09/mysql-50-stored-procedures-getting.html' title='MySQL 5.0 Stored Procedures : Getting Started'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>73</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112748491808582579</id><published>2005-09-23T14:00:00.000Z</published><updated>2005-09-23T14:15:18.093Z</updated><title type='text'>MySQL on the Mac</title><content type='html'>I read with interest Zack Urlocker's blog entry for today on his experience with a new Intel based Mac MySQL have recently got their hands on. I was looking for a new PC at the start of the year, maily because of some problems with my current windows box having problems communicating with various USB devices. I've always liked the look of Macs but the expense has always put me off, I'm not made of money after all. &lt;br /&gt;&lt;br /&gt;But lucky for me (and apple), my looking for a new PC coincided with Steve Jobs announcment of the Mac Mini. Anyway I'm sure you're not interested in my shopping habits so on to the important part. &lt;br /&gt;&lt;br /&gt;I purchased the Mac Mini to develop my website &lt;a href="http://www.mysqldevelopment.com"&gt;www.mysqldevelopment.com&lt;/a&gt; (shamless plug) on, that meant I needed some html writing software, an FTP client and of course a MySQL database. One of the great things which became apparent straight away was that the MySQL command line client is identical to the Windows version that I had been using before, this meant that there was zero downtime waiting for me to get up to speed with using MySQL on the Mac. The other great thing was that all the scripts I produced were immediately portable to the windows (or Linux) versions of MySQL. &lt;br /&gt;&lt;br /&gt;To try and tie this in to the theme of this blog (a guide to MySQL for Oracle users) it's the same with Oracle's SQL*Plus, it's the same on any platform Oracle supports (which is pretty much everything). &lt;br /&gt;&lt;br /&gt;So if the switch to Intel by apple has put the seed in your head, don't worry for a second about running MySQL, it works just the way you like it. &lt;br /&gt;&lt;br /&gt;Here ends the Mac/MySQL plug.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112748491808582579?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112748491808582579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112748491808582579' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112748491808582579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112748491808582579'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/09/mysql-on-mac.html' title='MySQL on the Mac'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112686463863615191</id><published>2005-09-16T09:34:00.000Z</published><updated>2005-09-16T09:57:44.416Z</updated><title type='text'>5.0.13 Coming to a MySQL installation soon</title><content type='html'>I've taken a great deal of interest in version 5 of MySQL, mainly because of my background in procedural extensions for other databases. It's been pretty exciting watching the development of version 5 and as somebody who has been keen to exploit the features I've been running as current a version as possible (it's currently at 5.0.12), this has meant at times a bi-weekly installation of the latest version.&lt;br /&gt;&lt;br /&gt;One of the biggest requests from people on the stored procedures forum over on the MySQL website has been for information on using prepared statements, I'll gloss over the fact that for 90% of these situations prepared statements are not the way to go. MySQL Stored Procedures did infact support prepared statements for a while but this support was removed in version 5.0.9, this caused all manner of confusion and fist waving by the masses and resulted in a flood of angry forum entires asking where they had gone and why MySQL had pulled the plug.... &lt;br /&gt;&lt;br /&gt;...the great news is that the latest release notes for MySQL 5.0.13 tell us they are back. For the moment they will only be supported in Stored Procedures and not Functions or Triggers. The bad news is that 5.0.13 hasn't been released yet (at least not at the time of writing) so all you prepared statement fans need to hold on just a little longer. &lt;br /&gt;&lt;br /&gt;Now all we need to do is to convince people that a monster stored procedure with 25 parameters to build all their SQL calls dynamically isn't the best use of stored procedures ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112686463863615191?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112686463863615191/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112686463863615191' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112686463863615191'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112686463863615191'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/09/5013-coming-to-mysql-installation-soon.html' title='5.0.13 Coming to a MySQL installation soon'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112608282254436291</id><published>2005-09-07T08:45:00.000Z</published><updated>2005-09-07T08:47:02.550Z</updated><title type='text'>Sorry</title><content type='html'>It seems the day job has finally caught up with me. I've been so busy that I haven't had time to update this blog in a few weeks. But please do keep checking back as we should be back to normal service soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112608282254436291?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112608282254436291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112608282254436291' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112608282254436291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112608282254436291'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/09/sorry.html' title='Sorry'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112480905033777419</id><published>2005-08-23T14:49:00.000Z</published><updated>2005-08-23T15:01:08.103Z</updated><title type='text'>DUAL</title><content type='html'>Most of the time when you are using SQL you will be selecting against a table in your database. But there are the odd occassions where you don't actually want to select something from a table but still display information. &lt;br /&gt;&lt;br /&gt;In Oracle this is handled by the DUAL table. DUAL is a single row all purpose table which allows you to issue a select statement on values which are not stored in an actual table. Take for example the sysdate function which returns the current date. &lt;br /&gt;&lt;pre style="color:red"&gt;&lt;br /&gt;SQL&gt; select sysdate from dual;&lt;br /&gt;&lt;br /&gt;SYSDATE&lt;br /&gt;---------&lt;br /&gt;23-AUG-05&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;MySQL has full support for the DUAL table also. &lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;mysql&gt; select curdate() from dual;&lt;br /&gt;+------------+&lt;br /&gt;| curdate()  |&lt;br /&gt;+------------+&lt;br /&gt;| 2005-08-23 |&lt;br /&gt;+------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However MySQL doesn't really need the DUAL table to return values. You can simply issue a select statement that doesn't have a from clause. It's perfectly legal and in fact the most common way to select values that don't belong in a table. &lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;mysql&gt; select curdate();&lt;br /&gt;+------------+&lt;br /&gt;| curdate()  |&lt;br /&gt;+------------+&lt;br /&gt;| 2005-08-23 |&lt;br /&gt;+------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can use this method to return information about the MySQL server or perform calculations. It's especially good for testing SQL you are going to use in the select section of an SQL statement.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;color:red;"&gt;Warning : &lt;/span&gt;It should be noted that you shouldn't issue anything other than select statements against the DUAL table, issuing INSERTS, UPDATES and worst of all DELETES against DUAL can have at least undesirable results.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112480905033777419?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112480905033777419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112480905033777419' title='119 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112480905033777419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112480905033777419'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/dual.html' title='DUAL'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>119</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112480854710113269</id><published>2005-08-23T14:47:00.000Z</published><updated>2005-08-23T14:49:07.113Z</updated><title type='text'>Wizzy Colours</title><content type='html'>You may have noticed in today's entry the SQL was shown in red and orange. I just wanted to point out if it wasn't obvious from now on any SQL or Code shown in red relates to Oracle and anything in Orange relaters to MySQL.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112480854710113269?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112480854710113269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112480854710113269' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112480854710113269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112480854710113269'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/wizzy-colours.html' title='Wizzy Colours'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112479120873895512</id><published>2005-08-23T09:06:00.000Z</published><updated>2005-08-23T10:00:08.756Z</updated><title type='text'>Outer Joins</title><content type='html'>Depending on the amount of experience you have with databases in general it's likely that as an Oracle user you would use the Oracle sytle join syntax. From version 9i Oracle has supported the ANSI join syntax but many users and many examples of Oracle SQL on the web still use the Oracle syntax. &lt;br /&gt;&lt;br /&gt;Essentially the Oracle syntax uses the where clause to specifiy the join condition simply by comparing a column in one table with the other. &lt;br /&gt;&lt;pre style="color:red"&gt;&lt;br /&gt;SQL&gt; select e.emp_id, d.description from emp e, dept d&lt;br /&gt;  2  where e.dept_id = d.dept_id;&lt;br /&gt;&lt;br /&gt;    EMP_ID DESCRIPTION&lt;br /&gt;---------- ------------------------------&lt;br /&gt;         1 HR&lt;br /&gt;         2 HR&lt;br /&gt;         3 IT&lt;br /&gt;         4 ADMIN&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The good news is that this also works in MySQL. MySQL fully supports ANSI join conditions but it also allows (in part) the joining of tables via the where clause. &lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;mysql&gt; select e.emp_name, d.description from emps e, dept d&lt;br /&gt;    -&gt; where e.dept_id = d.dept_id;&lt;br /&gt;+----------+-------------+&lt;br /&gt;| emp_name | description |&lt;br /&gt;+----------+-------------+&lt;br /&gt;| Paul     | IT          |&lt;br /&gt;| John     | HR          |&lt;br /&gt;| Alan     | IT          |&lt;br /&gt;+----------+-------------+&lt;br /&gt;3 rows in set (0.02 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The bad news is that you can't use the Oracle outer join syntax. In a normal join, know as an inner join only rows where the join matches exactly are returned. This means that in our example above if an employee record does not have a dept_id (or at least one which isn't in the dept table) the record will not be displayed. If we want to display all the records in a table regardless of the fact there may not be a match we can use an outer join. &lt;br /&gt;&lt;br /&gt;In Oracle to use an outer join we can simply use (+) against the table we are joining against, so for example.&lt;br /&gt;&lt;pre style="color:red"&gt;&lt;br /&gt;SQL&gt; select e.emp_id, d.description from emp e, dept d&lt;br /&gt;  2  where e.dept_id = d.dept_id(+);&lt;br /&gt;&lt;br /&gt;    EMP_ID DESCRIPTION&lt;br /&gt;---------- ------------------------------&lt;br /&gt;         1 HR&lt;br /&gt;         2 HR&lt;br /&gt;         3 IT&lt;br /&gt;         4 ADMIN&lt;br /&gt;         5&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We can now see a new record that wasn't shown in the first select. In Oracle we can simply move the (+) to either column the join is used against to specify which table to perform the outer join on. &lt;br /&gt;&lt;pre style="color:red"&gt;&lt;br /&gt;SQL&gt; select e.emp_id, d.description from emp e, dept d&lt;br /&gt;  2   where e.dept_id(+) = d.dept_id;&lt;br /&gt;&lt;br /&gt;    EMP_ID DESCRIPTION&lt;br /&gt;---------- ------------------------------&lt;br /&gt;         1 HR&lt;br /&gt;         2 HR&lt;br /&gt;         3 IT&lt;br /&gt;         4 ADMIN&lt;br /&gt;           PR&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As mentioned MySQL doesn't support (+) for outer joins. You therefore need to use the ANSI join syntax. We won't go into the full syntax here, but to use an outer join you need to use the left outer join keywords between the table definitions. The biggest difference is that the join condition becomes part of the from clause. &lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;mysql&gt; select e.emp_name, d.description &lt;br /&gt;       from emps e left outer join dept d &lt;br /&gt;       on e.dept_id = d.dept_id;&lt;br /&gt;&lt;br /&gt;+----------+-------------+&lt;br /&gt;| emp_name | description |&lt;br /&gt;+----------+-------------+&lt;br /&gt;| Barry    | NULL        |&lt;br /&gt;| Paul     | IT          |&lt;br /&gt;| John     | HR          |&lt;br /&gt;| Alan     | IT          |&lt;br /&gt;+----------+-------------+&lt;br /&gt;4 rows in set (0.11 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using the ANSI standard you can change which table is treated as the outer table by changing the LEFT keyword to RIGHT. &lt;br /&gt;&lt;pre style="color:orange"&gt;&lt;br /&gt;select e.emp_name, d.description &lt;br /&gt;       from emps e right outer join dept d &lt;br /&gt;       on e.dept_id = d.dept_id;&lt;br /&gt;&lt;br /&gt;+----------+-------------+&lt;br /&gt;| emp_name | description |&lt;br /&gt;+----------+-------------+&lt;br /&gt;| Paul     | IT          |&lt;br /&gt;| Alan     | IT          |&lt;br /&gt;| John     | HR          |&lt;br /&gt;+----------+-------------+&lt;br /&gt;3 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112479120873895512?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112479120873895512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112479120873895512' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112479120873895512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112479120873895512'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/outer-joins.html' title='Outer Joins'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112444526045907840</id><published>2005-08-19T09:24:00.000Z</published><updated>2005-08-19T10:00:08.193Z</updated><title type='text'>Metadata (a very brief introduction)</title><content type='html'>One of the great features of Oracle is the amount of Metadata available. For those that don't know metadata is essentially data about data, in Oracles case this is large number of tables which detail every aspect of the database objects. &lt;br /&gt;&lt;br /&gt;In general there are 2 groups, the user tables and the all tables. The user tables give information about the current users database objects and the all tables which detail information for every user (schema). &lt;br /&gt;&lt;br /&gt;The metadata is stored in tables, which can be accessed using SQL in the same way your normal tables are accessed. &lt;br /&gt;&lt;br /&gt;For example lets say you want to see all of the tables owner by your user. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select table_name from user_tables where rownum &lt; 10;&lt;br /&gt;&lt;br /&gt;TABLE_NAME&lt;br /&gt;------------------------------&lt;br /&gt;ADMIN_CHART&lt;br /&gt;ADMIN_CHART_ITEM&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;SUBCATEGORY&lt;br /&gt;SYSTEM_PARAMETER&lt;br /&gt;ZENDOR_STOCK_FEED&lt;br /&gt;&lt;br /&gt;63 rows selected.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;If we want to see all of the tables for all of the users we can use the all_tables view (the metadata tables are infact views on far more complex metadata tables).&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select table_name from all_tables where rownum &lt; 10;&lt;br /&gt;&lt;br /&gt;TABLE_NAME&lt;br /&gt;------------------------------&lt;br /&gt;SEG$&lt;br /&gt;CLU$&lt;br /&gt;OBJ$&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;WISHLIST&lt;br /&gt;WISHLIST_EVENT_NAME&lt;br /&gt;WISHLIST_ITEM&lt;br /&gt;&lt;br /&gt;831 rows selected.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So how does MySQL handle metadata? It depends on your version, most people will be running verison 4.1 or under, In these versions metadata is accessed using the show command. The show command consists of 22 different types of information about the database. The full list can be found here. &lt;br /&gt;&lt;a href="http://dev.mysql.com/doc/mysql/en/show.html"&gt;http://dev.mysql.com/doc/mysql/en/show.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The biggest difference between show and Oracles approach is that the show command offers very limited selection requirements, it's pretty much all or nothing. In our examples above we limited our selection to show the table name only, but there are over 40 columns we can use. MySQL's show command does not allow use to pick and choose which of the columns we would like to see. There is support for a like keyword on some of the show commands but this is limited to say the table name or session variable name. &lt;br /&gt;&lt;br /&gt;To see a list of tables in MySQL we can issue the SHOW TABLES command.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; show tables;&lt;br /&gt;+----------------+&lt;br /&gt;| Tables_in_pers |&lt;br /&gt;+----------------+&lt;br /&gt;| clientdata     |&lt;br /&gt;| dept           |&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;| test_letters   |&lt;br /&gt;| test_order     |&lt;br /&gt;| test_select    |&lt;br /&gt;+----------------+&lt;br /&gt;14 rows in set (0.14 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;From version 5.0 (not currently a full release) MySQL have introduced the information_schema. This replicates the functionality of the metadata tables of Oracle. MySQL users can now use SQL statements against these new tables to select particular columns, use where clauses and group by. A list of the information schema tables cab be found here. &lt;br /&gt;&lt;a href="http://dev.mysql.com/doc/mysql/en/information-schema-tables.html"&gt;http://dev.mysql.com/doc/mysql/en/information-schema-tables.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So we can see a list of tables using the information_schema like so.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select table_name from information_schema.tables;&lt;br /&gt;+---------------------------------------+&lt;br /&gt;| table_name                            |&lt;br /&gt;+---------------------------------------+&lt;br /&gt;| SCHEMATA                              |&lt;br /&gt;| TABLES                                |&lt;br /&gt;| COLUMNS                               |&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;| test_text                             |&lt;br /&gt;| ts_data                               |&lt;br /&gt;+---------------------------------------+&lt;br /&gt;63 rows in set (1.74 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112444526045907840?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112444526045907840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112444526045907840' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112444526045907840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112444526045907840'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/metadata-very-brief-introduction.html' title='Metadata (a very brief introduction)'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112435831881628890</id><published>2005-08-18T09:38:00.000Z</published><updated>2005-08-18T09:48:30.096Z</updated><title type='text'>New Blog</title><content type='html'>Roland Bouman has started a new blog available here. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://rpbouman.blogspot.com/"&gt;http://rpbouman.blogspot.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Roland is a very active member of the MySQL community especailly in the areas of Stored Procedures, Triggers and Views. He is also written some great work with the new information schema available in version 5 of MySQL. I'll admit to some bias as Roland has worked with me on www.mysqldevelopment.com&lt;br /&gt;&lt;br /&gt;You can see some of Rolands work here. &lt;br /&gt;&lt;a href="http://mysql.gilfster.com/page.php?parent_id=6&amp;page_id=6.0.1"&gt;http://mysql.gilfster.com/page.php?parent_id=6&amp;page_id=6.0.1&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112435831881628890?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112435831881628890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112435831881628890' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112435831881628890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112435831881628890'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/new-blog.html' title='New Blog'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112420114718748464</id><published>2005-08-16T13:59:00.000Z</published><updated>2005-08-16T14:06:28.303Z</updated><title type='text'>SOUNDEX</title><content type='html'>If you have read any Oracle SQL Manuals or books you may have come across the SOUNDEX function. The function returns a value based on the phonetic representation of a string you supplied, this can then be used to compare with another word which sounds the same. &lt;br /&gt;&lt;br /&gt;Soundex is available in MySQL also and operates in exactly the same way. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from sound_test&lt;br /&gt;       where soundex(word) = soundex('to');&lt;br /&gt;+------+&lt;br /&gt;| word |&lt;br /&gt;+------+&lt;br /&gt;| to   |&lt;br /&gt;| too  |&lt;br /&gt;+------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However MySQL also offers a much easier way of using and remembering the functionality. All you need to do is use the words &lt;span style="font-weight:bold;"&gt;sounds like&lt;/span&gt; as the comparison to perform the same functionality. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from sound_test &lt;br /&gt;       where word sounds like 'to';&lt;br /&gt;+------+&lt;br /&gt;| word |&lt;br /&gt;+------+&lt;br /&gt;| to   |&lt;br /&gt;| too  |&lt;br /&gt;+------+&lt;br /&gt;2 rows in set (0.05 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112420114718748464?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112420114718748464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112420114718748464' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112420114718748464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112420114718748464'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/soundex.html' title='SOUNDEX'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112418719020651875</id><published>2005-08-16T09:34:00.000Z</published><updated>2005-08-16T10:14:31.610Z</updated><title type='text'>Concat</title><content type='html'>Often when dealing with text in an SQL statements it's desirable to join two or more strings together. For example we might want to join a persons title and surname to produce a suitable heading for an address block. &lt;br /&gt;&lt;br /&gt;This joining of words is called concatenation and in Oracle is achieved using the pipe character twice like so ||&lt;br /&gt;&lt;pre&gt; &lt;br /&gt;SQL&gt; select title||' '||surname from person;&lt;br /&gt;&lt;br /&gt;TITLE||''||SURNAME&lt;br /&gt;-----------------------------------------&lt;br /&gt;Mr Miller&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In MySQL concatenation is achieved using a function called concat. All we need to do is call the concat function from the SQL statement passing in the columns or text we wish to concatenate. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select concat(title,' ',surname) from person&lt;br /&gt;+---------------------------+&lt;br /&gt;| concat(title,' ',surname) |&lt;br /&gt;+---------------------------+&lt;br /&gt;| Mr Miller                 |&lt;br /&gt;+---------------------------+&lt;br /&gt;1 row in set (0.02 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However we can use an SQL Server Mode parameter to allow us to use the pipe character as we would in Oracle. SQL Server Modes are settings which change the behaviour of the server for an individual client. To use pipes for concatenation we can use the PIPES_AS_CONCAT option. This is set as follows. &lt;br /&gt;&lt;pre&gt; &lt;br /&gt;set sql_mode = 'PIPES_AS_CONCAT';&lt;br /&gt;&lt;/pre&gt;  &lt;br /&gt;So we can see this in action like so. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select title||' '||surname from person;&lt;br /&gt;+---------------------+&lt;br /&gt;| title||' '||surname |&lt;br /&gt;+---------------------+&lt;br /&gt;|                   0 |&lt;br /&gt;+---------------------+&lt;br /&gt;1 row in set (0.02 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; set sql_mode = 'PIPES_AS_CONCAT';&lt;br /&gt;Query OK, 0 rows affected (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select title||' '||surname from person;&lt;br /&gt;+---------------------+&lt;br /&gt;| title||' '||surname |&lt;br /&gt;+---------------------+&lt;br /&gt;| Mr Miller           |&lt;br /&gt;+---------------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You may have noticed that the first call using the pipe characters does not cause an error, this is because the double pipe is used as a synonum for OR in MySQL. You should use PIPES_AS_CONCAT with caution for this reason.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112418719020651875?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112418719020651875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112418719020651875' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112418719020651875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112418719020651875'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/concat.html' title='Concat'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112410963083134488</id><published>2005-08-15T12:29:00.000Z</published><updated>2005-08-15T12:40:30.840Z</updated><title type='text'>CREATE TABLE LIKE</title><content type='html'>As with Oracle MySQL offers the ability to create a table based on the definition of another. This can be done in two ways, one which will be familiar to Oracle users and another which is only available in MySQL.&lt;br /&gt;&lt;br /&gt;The first way is to use a select statement in the create table command like so. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; create table emps2 as select * from emps;&lt;br /&gt;Query OK, 3 rows affected (0.20 sec)&lt;br /&gt;Records: 3  Duplicates: 0  Warnings: 0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This creates a table with the same structure as the table we based the select statement on. We can add or remove columns from the table by explicitly specifying the column names in the select like so. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; create table emps3 as select emp_id, emp_name from emps;&lt;br /&gt;Query OK, 3 rows affected (0.13 sec)&lt;br /&gt;Records: 3  Duplicates: 0  Warnings: 0&lt;br /&gt;&lt;br /&gt;mysql&gt; desc emps3;&lt;br /&gt;+----------+-------------+------+-----+---------+-------+&lt;br /&gt;| Field    | Type        | Null | Key | Default | Extra |&lt;br /&gt;+----------+-------------+------+-----+---------+-------+&lt;br /&gt;| emp_id   | int(11)     | NO   |     | 0       |       |&lt;br /&gt;| emp_name | varchar(30) | YES  |     | NULL    |       |&lt;br /&gt;+----------+-------------+------+-----+---------+-------+&lt;br /&gt;2 rows in set (0.05 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The good thing about using this method is that it populates the table with the data from the select statement also. This makes it a great way to backup tables before running potentially damaging SQL against them. If you want the new table to be empty once it's created you can simply specify a where clause that returns no rows. Personally I use WHERE 1=2 as unless the rules of mathmatics change will always be false and hence return no rows. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; create table emps4 as select emp_id, emp_name from emps where 1=2;&lt;br /&gt;Query OK, 0 rows affected (0.13 sec)&lt;br /&gt;Records: 0  Duplicates: 0  Warnings: 0&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from emps4;&lt;br /&gt;Empty set (0.00 sec)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;One downside to this approach on both MySQL and Oracle is that it doesn't make an exact replica of the table, for example any index against the table will not be receated for the new table. &lt;br /&gt;&lt;br /&gt;MySQL however offers a solution to this with the LIKE keyword. This can be used to create a table based on the definition of another. This is done as follows. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; create table emps5 like emps;&lt;br /&gt;Query OK, 0 rows affected (0.06 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from emps5;&lt;br /&gt;Empty set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The downside of this method is that the data isn't copied across in the way it is using an SQL statement in the create. But it's easy to do that using a command like follows. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; insert into emps5 select * from emps;&lt;br /&gt;Query OK, 3 rows affected (0.05 sec)&lt;br /&gt;Records: 3  Duplicates: 0  Warnings: 0&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112410963083134488?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112410963083134488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112410963083134488' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112410963083134488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112410963083134488'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/create-table-like.html' title='CREATE TABLE LIKE'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112410874024349305</id><published>2005-08-15T12:17:00.000Z</published><updated>2005-08-15T12:25:40.250Z</updated><title type='text'>It's Official.....</title><content type='html'>...seems some people are actually reading my Blog, it's difficult to know sometimes as there isn't the sort of statistics available for me to find out. However I have received a couple of emails about the blog over the last few days.&lt;br /&gt;&lt;br /&gt;One thing I didn't realise is that to leave a comment you need a blogger account, I have changed the setting so you can now leave comments without having to sign up for an account. &lt;br /&gt;&lt;br /&gt;I was also asked about a feed, this is available at &lt;br /&gt;&lt;br /&gt;http://gilfster.blogspot.com/atom.xml&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112410874024349305?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112410874024349305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112410874024349305' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112410874024349305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112410874024349305'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/its-official.html' title='It&apos;s Official.....'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112386317471219039</id><published>2005-08-12T16:11:00.000Z</published><updated>2005-08-12T16:13:26.050Z</updated><title type='text'>Sorry</title><content type='html'>I've been extremely busy this week so the blog hasn't been updated in a few days. If you are following the blog we would love to hear from you. &lt;br /&gt;&lt;br /&gt;I'll update the blog over the weekend with 2 new articles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112386317471219039?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112386317471219039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112386317471219039' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112386317471219039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112386317471219039'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/sorry.html' title='Sorry'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112367642328124100</id><published>2005-08-10T12:08:00.000Z</published><updated>2005-08-10T12:20:23.286Z</updated><title type='text'>Temporary Tables</title><content type='html'>In Oracle it's possible to create temporary tables. The name is a little missleading in that the table itself is not temporary but the data inside is. There are 2 basic types of temporary tables, those that clear the information in them apon a commit and those which preserve the rows when a commit takes place. However the data is always cleared from the table when the user ends their session. &lt;br /&gt;&lt;br /&gt;The other feature of temporary tables in Oracle is that the data is available to the current session. Therefore 2 users can use the table without fear of causing problems in other sessions. &lt;br /&gt;&lt;br /&gt;MySQL also supports temporary tables, but the big difference is that they &lt;span style="font-weight:bold;"&gt;are&lt;/span&gt; temporary. This means that they are only available during the current session, once the session has ended the table is dropped automatically. This means they do not exists as an object in the database and therefore need to be recreated each time they are to be used. &lt;br /&gt;&lt;br /&gt;Like Oracle the data contained within them is available to the current session only, however unlike Oracle users can create temporary tables with the same name and a completely different structure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112367642328124100?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112367642328124100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112367642328124100' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112367642328124100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112367642328124100'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/temporary-tables.html' title='Temporary Tables'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112358625146765951</id><published>2005-08-09T10:57:00.000Z</published><updated>2005-08-09T11:17:31.473Z</updated><title type='text'>Why switch from Oracle to MySQL at all.</title><content type='html'>I got an email from Curt Monash, the president of Monash Information Services this morning. He raised a good point, why would you want to switch to MySQL from Oracle? You can check out his blog here &lt;a href="http://www.dbms2.com/"&gt;http://www.dbms2.com/&lt;/a&gt; which just a quick look will give you an indication on why he's asking. &lt;br /&gt;&lt;br /&gt;This site isn't really meant to be a MySQL properganda page. I became interested in MySQL development mainly because I wanted to try and implement something along the lines of Oracle's PL/SQL Web tool kit and that took me along a path of looking at MySQL's new Version 5.0 and it's implementation of Stored Procedures. &lt;br /&gt;&lt;br /&gt;But what I did find was that despite the fact Oracle and MySQL are supposed to support ANSI standard SQL there are enough differences to annoy your average Oracle developer. This blog is aimed at those people who have been using Oracle for some time but just want to get to know those little tricks they used with Oracle but in MySQL. &lt;br /&gt;&lt;br /&gt;So back to the question of why you might want to switch. The first and most obvious answer is that for most purposes MySQL is free. You can download and install Oracle as a developer with out cost but to use it in a production environment is expensive. Secondly and somewhat related to the first point is that a large majority of basic web hosting packages provide support for MySQL. As a database Oracle and MySQL are pretty comparable, but it's some of the advance features that might make a large corporation go for Oracle, but do you need them. I've worked with Oracle for a number of years and used only a few of the more advanced features, you just don't need them most of the time. &lt;br /&gt;&lt;br /&gt;The final thing to say is that the staff at MySQL are extremely responsive both in terms of contact with reagards to bugs and feature requests and also on a personall level. I have written a number of white papers and web content on MySQL 5.0, and without any prompting on my part I have had a lot of communication with MySQL staff on the subject. It seems they appreciate what the community at large is doing and see that as a central part of their future plans.&lt;br /&gt;&lt;br /&gt;So in summary, it's free in most cases, it's well supported by web hosting companies, it has all the features you need for a small to medium database (if not a large one) and MySQL are open, friendly and a joy to deal with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112358625146765951?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112358625146765951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112358625146765951' title='101 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112358625146765951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112358625146765951'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/why-switch-from-oracle-to-mysql-at-all.html' title='Why switch from Oracle to MySQL at all.'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>101</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112324288840961597</id><published>2005-08-05T11:46:00.000Z</published><updated>2005-08-05T11:55:52.533Z</updated><title type='text'>Case Sensitivity in MySQL</title><content type='html'>Oracle is case sensitive when dealing with equality in select statements. So if we enter names with a capital in the first character position we need to specify the exact case to get a match. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select * from test_case where name  = 'dave';&lt;br /&gt;&lt;br /&gt;no rows selected&lt;br /&gt;&lt;br /&gt;SQL&gt; select * from test_case where name  = 'Dave';&lt;br /&gt;&lt;br /&gt;NAME&lt;br /&gt;----------&lt;br /&gt;Dave&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However MySQL is case insensitive in the same scenario. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; insert into test_case values ('Dave');&lt;br /&gt;Query OK, 1 row affected (0.03 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from test_case where name  = 'dave';&lt;br /&gt;+------+&lt;br /&gt;| name |&lt;br /&gt;+------+&lt;br /&gt;| Dave |&lt;br /&gt;+------+&lt;br /&gt;1 row in set (0.03 sec)&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;To force MySQL to check for an exact case we can use the &lt;span style="font-weight:bold;"&gt;binary&lt;/span&gt; keyword. This is simply placed before the comparison we want to evaluate. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from test_case where binary name  = 'dave';&lt;br /&gt;Empty set (0.01 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from test_case where binary name  = 'Dave';&lt;br /&gt;+------+&lt;br /&gt;| name |&lt;br /&gt;+------+&lt;br /&gt;| Dave |&lt;br /&gt;+------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;However you can make a column case senstive by adding the binary keyword to the create table creation statement. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; create table test_case (name varchar(30) binary);&lt;br /&gt;Query OK, 0 rows affected (0.11 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; insert into test_case values ('Dave');&lt;br /&gt;Query OK, 1 row affected (0.02 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from test_case where name  = 'dave';&lt;br /&gt;Empty set (0.02 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112324288840961597?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112324288840961597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112324288840961597' title='18 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112324288840961597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112324288840961597'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/case-sensitivity-in-mysql.html' title='Case Sensitivity in MySQL'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>18</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112314893062468540</id><published>2005-08-04T09:26:00.000Z</published><updated>2005-08-04T09:48:50.643Z</updated><title type='text'>Changing the MySQL command line tool</title><content type='html'>There are a number of GUI's for use with MySQL but being from an Oracle background I use the command line. I think it was Ford Prefect in Hitch Hikers Guide to the Galaxy that said always know where your SQL*Plus is (I think it was Towel actually). This is also true of MySQL which every OS version you're using you should be able to use the MySQL command line in exactly the same way on each machine. &lt;br /&gt;&lt;br /&gt;While the command line doesn't offer the same powerfull reporting abilities as SQL*Plus it is possible to change it's behaviour somewhat. &lt;br /&gt;&lt;br /&gt;Take for example the SQL*Plus command &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SET HEADING OFF&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Which turns off column headings during select statement execution like so...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQL&gt; select 'hello' as test from dual;&lt;br /&gt;&lt;br /&gt;TEST&lt;br /&gt;-----&lt;br /&gt;hello&lt;br /&gt;&lt;br /&gt;SQL&gt; set heading off&lt;br /&gt;SQL&gt; select 'hello' as test from dual;&lt;br /&gt;&lt;br /&gt;hello&lt;br /&gt;&lt;br /&gt;SQL&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This can be replicated in mysql using the -N switch when starting the command line tool.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;C:\Documents and Settings\Andrew&gt;mysql -u root -p -N&lt;br /&gt;Enter password: ********&lt;br /&gt;Welcome to the MySQL monitor.  Commands end with ; or \g.&lt;br /&gt;Your MySQL connection id is 17 to server version: 5.0.7-beta-nt&lt;br /&gt;&lt;br /&gt;Type 'help;' or '\h' for help. Type '\c' to clear the buffer.&lt;br /&gt;&lt;br /&gt;mysql&gt; use pers&lt;br /&gt;Database changed&lt;br /&gt;mysql&gt; select * from emps;&lt;br /&gt;+---+------+------+--------+&lt;br /&gt;| 1 | Paul | 1    | 999.99 |&lt;br /&gt;| 2 | John | 2    | 999.99 |&lt;br /&gt;| 3 | Alan | 1    | 999.99 |&lt;br /&gt;+---+------+------+--------+&lt;br /&gt;3 rows in set (0.16 sec)&lt;br /&gt;mysql&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Another common modification people make is to change the command line prompt in SQL*Plus this is done in MySQL using the --prompt switch or simply by using the word prompt on the MySQL command line. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; prompt MyPrompt &gt;&lt;br /&gt;PROMPT set to 'MyPrompt &gt;'&lt;br /&gt;MyPrompt &gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However MySQL offers a number of dynamic elements that you can use in the prompt. So for example lets say we wanted to see which database we are connected to we simply use \d when defining out prompt.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; prompt \d &gt;&lt;br /&gt;PROMPT set to '\d &gt;'&lt;br /&gt;pers &gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This means we don't need to keep changing the prompt when connecting to different databases, this sort of prompt in SQL*Plus is achieved using a login script, it then means using another script when changing connect, buy in MySQL this is all automatic.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;pers &gt;use information_schema&lt;br /&gt;Database changed&lt;br /&gt;information_schema &gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There are a number of options that can be used, a full list can be found here...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.mysql.com/doc/mysql/en/mysql-commands.html"&gt;http://dev.mysql.com/doc/mysql/en/mysql-commands.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112314893062468540?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112314893062468540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112314893062468540' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112314893062468540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112314893062468540'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/changing-mysql-command-line-tool.html' title='Changing the MySQL command line tool'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112297542613049530</id><published>2005-08-02T09:03:00.000Z</published><updated>2005-08-02T09:37:48.530Z</updated><title type='text'>Sequences in MySQL</title><content type='html'>In Oracle sequences are often used to maintain a unique series of numbers for an ID field. Sequences are independant of any table and can be used to keep a value unique across a number of tables. In fact they are not even restricted to use in tables.&lt;br /&gt;&lt;br /&gt;MySQL doesn't currently support sequences. However it does have an auto increment value which can be applied to a primary key of a table. This is done during the table creation. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; create table seq_test&lt;br /&gt;      (id int primary key auto_increment&lt;br /&gt;      ,name varchar(30));&lt;br /&gt;Query OK, 0 rows affected (0.06 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As the name suggests the value is assigned automatically, this is in contrast to Oracle where we have to call the nextval function of the sequence to return the value when we need it. &lt;br /&gt;&lt;br /&gt;So if we perform an insert against the table but do not specifiy a value for the auto_increment column it's assigned automatically. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; insert into seq_test (name) values ('Dave');&lt;br /&gt;Query OK, 1 row affected (0.03 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from seq_test;&lt;br /&gt;+----+------+&lt;br /&gt;| id | name |&lt;br /&gt;+----+------+&lt;br /&gt;|  1 | Dave |&lt;br /&gt;+----+------+&lt;br /&gt;1 row in set (0.03 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However we can override the assignment using a value of our choosing. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; insert into seq_test (id,name) values (100,'John');&lt;br /&gt;Query OK, 1 row affected (0.05 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from seq_test;&lt;br /&gt;+-----+------+&lt;br /&gt;| id  | name |&lt;br /&gt;+-----+------+&lt;br /&gt;|   1 | Dave |&lt;br /&gt;| 100 | John |&lt;br /&gt;+-----+------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The sequence will then start from this new higher point. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; insert into seq_test (name) values ('Penny');&lt;br /&gt;Query OK, 1 row affected (0.02 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from seq_test;&lt;br /&gt;+-----+-------+&lt;br /&gt;| id  | name  |&lt;br /&gt;+-----+-------+&lt;br /&gt;|   1 | Dave  |&lt;br /&gt;| 100 | John  |&lt;br /&gt;| 101 | Penny |&lt;br /&gt;+-----+-------+&lt;br /&gt;3 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We can insert records with values lower than the current highest value but these will be subject to the normal rules for a primary key (no duplicates) and will not effect the next number assigned automatically.&lt;br /&gt;&lt;br /&gt;If all of the records are deleted from a table the sequence is not reset. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; delete from seq_test;&lt;br /&gt;Query OK, 3 rows affected (0.01 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; insert into seq_test (name) values ('garry');&lt;br /&gt;Query OK, 1 row affected (0.03 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from seq_test;&lt;br /&gt;+-----+-------+&lt;br /&gt;| id  | name  |&lt;br /&gt;+-----+-------+&lt;br /&gt;| 103 | garry |&lt;br /&gt;+-----+-------+&lt;br /&gt;1 row in set (0.02 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To do this you need to truncate the table like so.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; truncate table seq_test;&lt;br /&gt;Query OK, 1 row affected (0.03 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; insert into seq_test (name) values ('garry');&lt;br /&gt;Query OK, 1 row affected (0.03 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select * from seq_test;&lt;br /&gt;+----+-------+&lt;br /&gt;| id | name  |&lt;br /&gt;+----+-------+&lt;br /&gt;|  1 | garry |&lt;br /&gt;+----+-------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Alternatively you can reset the sequence using an alter table command.&lt;br /&gt;&lt;pre&gt; &lt;br /&gt;mysql&gt; alter table seq_test auto_increment = 100;&lt;br /&gt;Query OK, 1 row affected (0.27 sec)&lt;br /&gt;Records: 1  Duplicates: 0  Warnings: 0&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;This method could also be used to assign a higher number to start the sequence rather than starting with 1 by calling the alter table straight after the table creation.&lt;br /&gt;&lt;br /&gt;So in summary auto_increment offers a great way of assigning a unique value automatically to a table. However what it doesn't allow when compared with an Oracle Sequence is different increment values, ability to use across a number of tables and the option to assign in a reverse order.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112297542613049530?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112297542613049530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112297542613049530' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112297542613049530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112297542613049530'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/sequences-in-mysql.html' title='Sequences in MySQL'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112290453343531170</id><published>2005-08-01T13:36:00.000Z</published><updated>2005-08-01T13:55:33.443Z</updated><title type='text'>Transactions in MySQL</title><content type='html'>In Oracle transactions are "turned on" by default, in other words DML statements (update, insert, delete) need to be commited or rolledback explicitly. It's possible to set your client, for example SQL*Plus, to auto commit for you but many Oracle developers (Myself included) are simply used to having to commit and rollback (and many times appreciate the fact when we forget to include a where clause on that delete statements). &lt;br /&gt;&lt;br /&gt;One of the great features of MySQL is it's ability to use different storage engines. The defualt storage engine is InnoDB which supports transactions, however the command line client and Query Browser will commit and DML automatically by default. &lt;br /&gt;&lt;br /&gt;If you need to use transactions you can do one of the following, &lt;br /&gt;&lt;br /&gt;explictily start a transaction using the following command, &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql &gt; START TRANSACTION;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This will then continue the transaction until a commit or rollback takes place. To start a new transaction you need to issue the start transaction statment again.&lt;br /&gt;&lt;br /&gt;If you would rather work in an environment like SQL*Plus where each and every statement needs to commited or rolled back you can use the SET command like so. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql &gt; SET AUTOCOMMIT = 0;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;A few points to note, when using transactions DDL does not perform a commit in the back ground, this &lt;u&gt;is&lt;/u&gt; the case in Oracle. However issuing a lock tables command will issue a commit, even if the table with the changes is not part of the lock tables command.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112290453343531170?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112290453343531170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112290453343531170' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112290453343531170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112290453343531170'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/08/transactions-in-mysql.html' title='Transactions in MySQL'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112263345578119367</id><published>2005-07-29T10:19:00.000Z</published><updated>2005-07-29T10:37:35.786Z</updated><title type='text'>Connecting to remote MySQL installations</title><content type='html'>A question that seems to have poped up a number of time this week over on the MySQL forums is how to connect to MySQL installations on a remote machine, be it on the same network or across the internet.&lt;br /&gt;&lt;br /&gt;If you have used Oracle the way to do this is to set up an entry in your tnsnames.ora file, for those that don't know this is a configuration file containing all of the information Oracle needs to connect to database either locally or remotely. &lt;br /&gt;&lt;br /&gt;If we are using the SQL*Plus command line client for Oracle we can connect to another server using the following command. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SQLPlus user/password@database &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The database portion is in fact a reference to an entry in the tnsnames.ora file which contains the machine name or IP address of the machine and database SID we want to connect to. &lt;br /&gt;&lt;br /&gt;In MySQL we don't need to use an additional file to connect to another instance, we simnply add a -h parameter to our call to mysql. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql -h hostname -u root -p &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This then connects us to the remote database. The -h can be a machine name, webserver or IP address.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112263345578119367?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112263345578119367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112263345578119367' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112263345578119367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112263345578119367'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/07/connecting-to-remote-mysql.html' title='Connecting to remote MySQL installations'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112256489381014144</id><published>2005-07-28T15:31:00.000Z</published><updated>2005-07-28T15:36:04.576Z</updated><title type='text'>Using IFNULL ( )</title><content type='html'>NVL() is a great function in Oracle to convert NULL columns into a more useable format, for example it's often the case on reports to convert NULL numeric columns to 0 for better readability. &lt;br /&gt;&lt;br /&gt;In MySQL you can use IFNULL() in the same way. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select emp_id, salary, bonus from salary;&lt;br /&gt;+--------+---------+-------+&lt;br /&gt;| emp_id | salary  | bonus |&lt;br /&gt;+--------+---------+-------+&lt;br /&gt;|      1 | 2000.00 |  NULL |&lt;br /&gt;+--------+---------+-------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;br /&gt;mysql&gt; select emp_id, salary, ifnull(bonus,0) from salary;&lt;br /&gt;+--------+---------+-----------------+&lt;br /&gt;| emp_id | salary  | ifnull(bonus,0) |&lt;br /&gt;+--------+---------+-----------------+&lt;br /&gt;|      1 | 2000.00 |            0.00 |&lt;br /&gt;+--------+---------+-----------------+&lt;br /&gt;1 row in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112256489381014144?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112256489381014144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112256489381014144' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112256489381014144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112256489381014144'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/07/using-ifnull.html' title='Using IFNULL ( )'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112254373331212533</id><published>2005-07-28T09:37:00.000Z</published><updated>2005-07-28T09:42:13.316Z</updated><title type='text'>Multi Row inserts</title><content type='html'>One of the features I like best in MySQL is the ability to insert mulitple rows of data using a single insert statement. In Oracle you need to write an insert statement for each row including the list of columns each time, but in MySQL you only need to list the column names you need once and then list the values clause multiple times. &lt;br /&gt;&lt;br /&gt;So in Oracle we have &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;insert into emps (emp_id, name, salary) &lt;br /&gt;values (1,'Dave',2000.00);&lt;br /&gt;&lt;br /&gt;insert into emps (emp_id, name, salary) &lt;br /&gt;values (2,'John',2100.00);&lt;br /&gt;&lt;br /&gt;insert into emps (emp_id, name, salary) &lt;br /&gt;values (3,'Barry',1900.00);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But in MySQL this can be done like so.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;insert into emps (emp_id, name, salary)&lt;br /&gt;values (1,'Dave',2000.00),(2,'John',2100.00),(3,'Barry',1900.00)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It's shorter, tidy and more logical.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112254373331212533?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112254373331212533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112254373331212533' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112254373331212533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112254373331212533'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/07/multi-row-inserts.html' title='Multi Row inserts'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112238215369070290</id><published>2005-07-26T12:46:00.000Z</published><updated>2005-07-26T12:49:23.683Z</updated><title type='text'>IF in SQL statements</title><content type='html'>In older versions of Oracle you can use DECODE to implement conditional logic within SQL statements, from 8i you can also use CASE. In MySQL the decode functionality is replicated using IF. &lt;br /&gt;&lt;br /&gt;IF is infact a function call rather than a part of the SQL syntax but it works pretty well in most cases. For example...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select if(emp_id=1,'X','Y') as test, emp_id from emps;&lt;br /&gt;+------+--------+&lt;br /&gt;| test | emp_id |&lt;br /&gt;+------+--------+&lt;br /&gt;| X    |      1 |&lt;br /&gt;| Y    |      2 |&lt;br /&gt;| Y    |      3 |&lt;br /&gt;+------+--------+&lt;br /&gt;3 rows in set (0.06 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112238215369070290?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112238215369070290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112238215369070290' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112238215369070290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112238215369070290'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/07/if-in-sql-statements.html' title='IF in SQL statements'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112229819674138718</id><published>2005-07-25T13:12:00.000Z</published><updated>2005-07-25T13:29:56.750Z</updated><title type='text'>group_concat</title><content type='html'>One great function I came across a few days ago is group_concat. Many times I've been asked to produce a query which pivots records in a table to take data which is presented in column format into a single row. In Oracle it can get pretty complicated either using a number of subqueries (which presents it's own problems) or analytical functions (which I'll admit I haven't used anywhere near enough). &lt;br /&gt;&lt;br /&gt;Sitting on my desk is a timesheet, lets say the boss wants the reporting flexibility of adding in data one day at a time, fine we just create a table like so... &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; create table ts_data(emp_id int, week_no int, work_date date, hours numeric(4,2));&lt;br /&gt;Query OK, 0 rows affected (0.11 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I'll insert some data so we get the following data set. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select * from ts_data;&lt;br /&gt;+--------+---------+------------+-------+&lt;br /&gt;| emp_id | week_no | work_date  | hours |&lt;br /&gt;+--------+---------+------------+-------+&lt;br /&gt;|      1 |       1 | 2005-07-18 |  8.00 |&lt;br /&gt;|      1 |       1 | 2005-07-19 |  8.00 |&lt;br /&gt;|      1 |       1 | 2005-07-20 |  8.00 |&lt;br /&gt;|      1 |       1 | 2005-07-21 |  8.00 |&lt;br /&gt;|      1 |       1 | 2005-07-22 |  8.00 |&lt;br /&gt;|      1 |       2 | 2005-07-23 |  8.00 |&lt;br /&gt;|      1 |       2 | 2005-07-24 |  8.00 |&lt;br /&gt;+--------+---------+------------+-------+&lt;br /&gt;7 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So let's say the boss wants to see one row for each week with all of the hours worked side by side. That's where group_concat comes in. All we need to do is set up our grouping rules, in this case group by emp_id and week_no then specify the data we want to concatenate on a single row. &lt;br /&gt;&lt;pre&gt;&lt;br /&gt;mysql&gt; select emp_id, week_no, group_concat(work_date,' - ', hours) from ts_data group by emp_id, week_no;&lt;br /&gt;+--------+---------+-------------------------------------------------------------------------------------------+&lt;br /&gt;| emp_id | week_no | group_concat(work_date,' - ', hours)                                                      |&lt;br /&gt;+--------+---------+-------------------------------------------------------------------------------------------+&lt;br /&gt;|      1 |       1 | 2005-07-18 - 8.00,2005-07-19 - 8.00,2005-07-20 - 8.00,2005-07-21 - 8.00,2005-07-22 - 8.00 |&lt;br /&gt;|      1 |       2 | 2005-07-23 - 8.00,2005-07-24 - 8.00                                                       |&lt;br /&gt;+--------+---------+-------------------------------------------------------------------------------------------+&lt;br /&gt;2 rows in set (0.00 sec)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112229819674138718?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112229819674138718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112229819674138718' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112229819674138718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112229819674138718'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/07/groupconcat.html' title='group_concat'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-112229710645948975</id><published>2005-07-25T13:05:00.000Z</published><updated>2005-07-25T13:11:46.460Z</updated><title type='text'>An Oracle Developers Journey</title><content type='html'>If you have visited this blog before you may notice I have deleted all of the previous posts (I'd be suprised if anybody was looking however as I was pretty laxed about updating it). &lt;br /&gt;&lt;br /&gt;This year I have been working with MySQL, building my site www.mysqldevelopment.com and working with various people in the MySQL community both on the MySQ forums and over at the Quest MySQL forums. I'm more of an Oracle developer, having worked with it for a number of years prior to looking into MySQL in a bit more detail late last year. I've been looking for something to do with the blog since I started it, it became pretty clear my private life is nowhere near interesting enough to maintain a blog on a daily basis. &lt;br /&gt;&lt;br /&gt;So as from today I'm going to be writing about MySQL, and in particular little tips and tricks I have picked up recently that seem to make MySQL more usable and easy to live with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-112229710645948975?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/112229710645948975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=112229710645948975' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112229710645948975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/112229710645948975'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/07/oracle-developers-journey.html' title='An Oracle Developers Journey'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13517334.post-111891147583572624</id><published>2005-06-16T08:36:00.000Z</published><updated>2005-06-16T08:44:35.840Z</updated><title type='text'>MySQL 5.0 Beta Challenge</title><content type='html'>You may have stumbled upon this blog via my site http://www.mysqldevelopment.com. You will therefore be aware of my work on the new features of MySQL 5.0.&lt;br /&gt;&lt;br /&gt;AB the owners of MySQL have just announced a MySQL 5.0 Beta challenge to try and promote and also get people testing the latest version of MySQL. I've been in contact with Edwin De Souza over at AB for a few weeks with regard to pushing the new features and I'll be adding more content to my site soon.&lt;br /&gt;&lt;br /&gt;But they need more help,  they need you guys to test, write content and get involved with the latest release. Check out the associated press release&lt;br /&gt;&lt;br /&gt;http://dev.mysql.com/tech-resources/articles/evaluating-mysql-5.0.html&lt;br /&gt;&lt;br /&gt;If you don't have the ability to install MySQL on one of your servers check out a new site which gives you free access to MySQL databases http://www.db4free.net&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13517334-111891147583572624?l=gilfster.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://gilfster.blogspot.com/feeds/111891147583572624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13517334&amp;postID=111891147583572624' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/111891147583572624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13517334/posts/default/111891147583572624'/><link rel='alternate' type='text/html' href='http://gilfster.blogspot.com/2005/06/mysql-50-beta-challenge.html' title='MySQL 5.0 Beta Challenge'/><author><name>Andrew Gilfrin</name><uri>http://www.blogger.com/profile/09929358844206555905</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='http://www.gilfster.com/andrew.gif'/></author><thr:total>4</thr:total></entry></feed>
