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

<channel>
	<title>Kevin Bedell on Internet Tech &#187; mysql</title>
	<atom:link href="http://www.kbedell.com/tag/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kbedell.com</link>
	<description>Discussions on Ruby on Rails, Agile Development and the Boston Tech Scene.</description>
	<lastBuildDate>Mon, 09 Jan 2012 15:40:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Basic Introduction to Mysql InnoDB Performance Tuning &#8211; What are the best resources?</title>
		<link>http://www.kbedell.com/2011/09/30/basic-introduction-to-mysql-innodb-performance-tuning-what-are-the-best-resources/</link>
		<comments>http://www.kbedell.com/2011/09/30/basic-introduction-to-mysql-innodb-performance-tuning-what-are-the-best-resources/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 12:48:49 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[lists]]></category>
		<category><![CDATA[resources]]></category>

		<guid isPermaLink="false">http://www.kbedell.com/?p=377</guid>
		<description><![CDATA[I used to manage a couple very large MySQL Databases (like, 1TB+). They were huge, unforgiving beasts with an endless appetite to cause me stomach problems. I read everything I could find on MySQL Performance Tuning and innodb. Here&#8217;s a summary of what helped me: 1. The book High Performance MySQL is good, but only [...]]]></description>
			<content:encoded><![CDATA[<p>I used to manage a couple very large MySQL Databases (like, 1TB+). They were huge, unforgiving beasts with an endless appetite to cause me stomach problems.</p>
<p>I read everything I could find on MySQL Performance Tuning and innodb. Here&#8217;s a summary of what helped me:</p>
<p> 1. The book <a href="http://www.amazon.com/gp/product/0596101716/ref=as_li_ss_tl?ie=UTF8&#038;tag=kevinbedellsh-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399369&#038;creativeASIN=0596101716">High Performance MySQL</a> is good, but only gets you so far.</p>
<p> 2. The blog <a href="http://www.mysqlperformanceblog.com/tag/innodb/">MySQL Performance Blog (this link is to their posts tagged &#8216;innodb&#8217;)</a> was the most useful overall resource I found on the net. They go into detail on a lot of innodb tuning issues. It gets &#8216;ranty&#8217; at times, but overall it&#8217;s great. Here&#8217;s another link there on <a href="http://www.mysqlperformanceblog.com/2007/11/01/innodb-performance-optimization-basics/">InnoDB Performance Optimization Basics</a> that&#8217;s good.</p>
<p> 3. The last main thing I did to learn it was to simply read the MySQL Docs themselves. I read how every last parameter works, changed them on my server and then did some basic profiling. After a while you figure out what works by running big queries and seeing what happens. Here&#8217;s a good place to start:<br />
<a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-tuning-troubleshooting.html">InnoDB Performance Tuning and Troubleshooting</a></p>
<p>In the end, it&#8217;s just experimenting and working through things until you gain enough knowledge to know what works.</p>
<p>Please share any other ideas, pointers or resources you know of in the comments &#8212; Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kbedell.com/2011/09/30/basic-introduction-to-mysql-innodb-performance-tuning-what-are-the-best-resources/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>MySQL Integer sizes and ranges of values &#8211; How-To Create Table example</title>
		<link>http://www.kbedell.com/2009/03/07/mysql-integer-sizes-and-ranges-of-values-how-to-create/</link>
		<comments>http://www.kbedell.com/2009/03/07/mysql-integer-sizes-and-ranges-of-values-how-to-create/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 18:40:18 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.kbedell.com/?p=124</guid>
		<description><![CDATA[There are 5 different integer columns, each hold integer values of different sizes. Moreover, each can be signed or unsigned. If your value can&#8217;t ever be negative (for example, for an index), then you should probably make your values unsigned. DROP TABLE `foo`.`example_03`; CREATE TABLE IF NOT EXISTS `foo`.`example_03` ( f_01 TINYINT, -- from -128 [...]]]></description>
			<content:encoded><![CDATA[<p>There are 5 different integer columns, each hold integer values of different sizes. </p>
<p>Moreover, each can be signed or unsigned. If your value can&#8217;t ever be negative (for example, for an index), then you should probably make your values unsigned.</p>
<pre>
DROP TABLE `foo`.`example_03`;
CREATE TABLE IF NOT EXISTS `foo`.`example_03` (
 f_01  TINYINT,           -- from -128 to 127
 f_02  TINYINT UNSIGNED,  -- from 0 to 256
 f_03  SMALLINT,          -- from -32,768 to 32,767
 f_04  SMALLINT UNSIGNED, -- from 0 to 65,535
 f_05  MEDIUMINT,         -- from -8,388,608 to 8,388,607
 f_06  MEDIUMINT UNSIGNED, -- from 0 to 16,777,215
 f_07  INT,               -- from -2,147,483,648 to 2,147,483,647
 f_08  INT UNSIGNED,      -- from 0 to 4,294,967,295
 f_09  BIGINT,
              -- from -9,223,372,036,854,775,808
              -- to  9,223,372,036,854,775,807
 f_10  BIGINT UNSIGNED    -- from 0 to 18,446,744,073,709,551,615
);
</pre>
<h5><a href="http://www.kbedell.com/mysql-programming/">Click here to go to the table of contents for all MySQL Programming Example Code</a></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.kbedell.com/2009/03/07/mysql-integer-sizes-and-ranges-of-values-how-to-create/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How-To MySQL CREATE TABLE Example showing default values, NULL values and comments</title>
		<link>http://www.kbedell.com/2009/03/07/how-to-mysql-example-showing-default-values-null-values-and-comments/</link>
		<comments>http://www.kbedell.com/2009/03/07/how-to-mysql-example-showing-default-values-null-values-and-comments/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 18:36:24 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.kbedell.com/?p=115</guid>
		<description><![CDATA[This example shows how to set default values for each column &#8212; as well as how to allow (or not allow) NULL values in the column. By default, any column can contain NULL values. (Note that we&#8217;re also using &#8220;CREATE TABLE IF NOT EXISTS&#8221; so an error doesn&#8217;t get thrown if the table already exists [...]]]></description>
			<content:encoded><![CDATA[<p>This example shows how to set default values for each column &#8212; as well as how to allow (or not allow) NULL values in the column. By default, any column can contain NULL values.</p>
<p>(Note that we&#8217;re also using &#8220;CREATE TABLE IF NOT EXISTS&#8221; so an error doesn&#8217;t get thrown if the table already exists when we try to create it.)</p>
<p>We&#8217;ve added comments as well, though we&#8217;ll explain those after.</p>
<pre>
/*
 Create the table foo.example_02 if it doesn't exist.
*/
CREATE TABLE IF NOT EXISTS `foo`.`example_02` (
 `field_1` VARCHAR(255) NOT NULL DEFAULT '',
 `field_2` CHAR(20) NOT NULL default 'default_text',
 `field_3` INT(10) DEFAULT NULL,
 `field_4` BIGINT(20),
 `field_5` DATETIME          -- embed a comment in the definition like this...
);
</pre>
<p>
Note that if you don&#8217;t specify NULL or NOT NULL, columns by default can contain NULL values. And not specifying a default is the same as specifying &#8216;DEFAULT NULL&#8217; since MySQL uses NULL as the default value in both cases.</p>
<p>Note also that I&#8217;ve added comments to the declaration. Comments come in two types &#8212; multi-line comments, and single-line comments. </p>
<pre>
/*
      This is a multi-line comment
*/

-- This is single-line comment 

select foo from bar;   -- This means the rest of this line is a comment
</pre>
<p />
<p />
<h5><a href="http://www.kbedell.com/mysql-programming/">Click here to go to the table of contents for all MySQL Programming Example Code</a></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.kbedell.com/2009/03/07/how-to-mysql-example-showing-default-values-null-values-and-comments/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Basic How-To Example of a MySQL CREATE TABLE command</title>
		<link>http://www.kbedell.com/2009/03/07/basic-how-to-example-of-a-mysql-create-table-command/</link>
		<comments>http://www.kbedell.com/2009/03/07/basic-how-to-example-of-a-mysql-create-table-command/#comments</comments>
		<pubDate>Sat, 07 Mar 2009 18:29:41 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[how-to]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.kbedell.com/?p=110</guid>
		<description><![CDATA[Here&#8217;s a basic example of a MySQL CREATE TABLE command. CREATE TABLE `foo`.`example_01` ( `field_1` VARCHAR(255), `field_2` CHAR(10), `field_3` INT(10), `field_4` BIGINT(20), `field_5` DATETIME ); Notice that the &#8216;back tic&#8217;s on each column definition (the little ` characters) are optional in most cases. I use them for reasons I&#8217;ll discuss later on. Also, for most [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a basic example of a MySQL CREATE TABLE command.</p>
<pre>
CREATE TABLE `foo`.`example_01` (
`field_1`         VARCHAR(255),
`field_2`         CHAR(10),
`field_3`         INT(10),
`field_4`         BIGINT(20),
`field_5`         DATETIME
);
</pre>
<p>
Notice that the &#8216;back tic&#8217;s on each column definition (the little ` characters) are optional in most cases. I use them for reasons I&#8217;ll discuss later on.</p>
<p />
Also, for most columns you see a number in parentheses after the name of the type &#8212; that is the default size for displaying that value in a select statement. </p>
<p>The actual size of the value you store in that column isn&#8217;t impacted by changing that number. Changing INT(10) to INT(12) won&#8217;t change the size of the data you can store in that column.</p>
<p/>
<h5><a href="http://www.kbedell.com/mysql-programming/">Click here to go to the table of contents for all MySQL Programming Example Code</a></h5>
]]></content:encoded>
			<wfw:commentRss>http://www.kbedell.com/2009/03/07/basic-how-to-example-of-a-mysql-create-table-command/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to get the contents of the database.yml file from ActiveRecord</title>
		<link>http://www.kbedell.com/2009/03/06/how-to-get-the-contents-of-the-database-ml-file-from-activerecord-and-connect-to-two-databases-at-once/</link>
		<comments>http://www.kbedell.com/2009/03/06/how-to-get-the-contents-of-the-database-ml-file-from-activerecord-and-connect-to-two-databases-at-once/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 14:09:17 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.kbedell.com/?p=70</guid>
		<description><![CDATA[Save to delicious. Sometimes when using Active Record you may want to create a database connection to a database other than the default database specified in your database.yml file. When this happens, the easiest way to do it is to use the Class-level convenience method on ActiveRecord::Base. Like this: Imagine your database.yml entry looks like [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://delicious.com/url/c5db65f90af6455a805484b6e7c67ccf">Save to delicious.</a></p>
<p>Sometimes when using Active Record you may want to create a database connection to a database other than the default database specified in your database.yml file.</p>
<p>When this happens, the easiest way to do it is to use the Class-level convenience method on ActiveRecord::Base. Like this:</p>
<p>Imagine your database.yml entry looks like this:</p>
<pre>development_foo:
  adapter: mysql
  encoding: utf8
  database: foo
  pool: 5
  username: my_user
  password: my_pass
  socket: /tmp/mysql.sock</pre>
<p>Now you want to create active record models that use that database connection. Here&#8217;s how:</p>
<pre># 'Bar' model points to the table 'bars' in the database 'foo'

class Bar &lt; ActiveRecord::Base

  # specify the database.yml entry
  $db_config = 'development_foo'

  # Fetch the database.yml configuration
  $config = ActiveRecord::Base.configurations[$db_config]

 # Now we can establish a connection to that database and
 # this ActiveRecord model class will point to that database.
  establish_connection $config

end</pre>
<p>It&#8217;s simple!</p>
<h6>Copyright Kevin Bedell, 2009<br />
All this code can be freely used under the terms of the MIT License.</h6>
]]></content:encoded>
			<wfw:commentRss>http://www.kbedell.com/2009/03/06/how-to-get-the-contents-of-the-database-ml-file-from-activerecord-and-connect-to-two-databases-at-once/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Simple Example of a MySQL Stored Procedure that uses a cursor</title>
		<link>http://www.kbedell.com/2009/03/02/a-simple-example-of-a-mysql-stored-procedure-that-uses-a-cursor/</link>
		<comments>http://www.kbedell.com/2009/03/02/a-simple-example-of-a-mysql-stored-procedure-that-uses-a-cursor/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 20:53:51 +0000</pubDate>
		<dc:creator>Kevin</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[how-to]]></category>

		<guid isPermaLink="false">http://www.kbedell.com/?p=18</guid>
		<description><![CDATA[(Save this to Del.icio.us!) What is a cursor and when should you use one? A &#8216;cursor&#8217; in MySQL is essentially just the result set that&#8217;s returned from a query. Using a cursor allows you to iterate, or step through, the results of a query and perform certain operations on each row that&#8217;s returned. Think of [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;">(<a href="http://delicious.com/url/1171b3104f173c8488c60cbb6f17ab4b">Save this to Del.icio.us!</a>)</p>
<h3>What is a cursor and when should you use one?</h3>
<p>A &#8216;cursor&#8217; in MySQL is essentially just the result set that&#8217;s returned from a query. Using a cursor allows you to iterate, or step through, the results of a query and perform certain operations on each row that&#8217;s returned.</p>
<p>Think of them like holders for any data you  might process in a loop. As you&#8217;ll see below, the example here runs a query then loops through the results.</p>
<p>Cursors have some drawbacks and you don&#8217;t want to use them everywhere. An appropriate use for a cursor might be when you need to step through the results of a query and then perform operations on multiple tables for each row.</p>
<p>Another candidate for a cursor is where some steps of the processing are optional and only need to be performed for certain rows. The cursor allows you to iterate through the result set and then perform the additional processing only on the rows that require it.</p>
<h3>When should cursors be avoided?</h3>
<p>Cursors should be avoided generally whenever you can write a SQL statement that processes all rows in a query at once &#8212; and you&#8217;ll be surprised at how often this is. If you try, many procedures with cursors in them can be refactored to eliminate the cursor by using a bit more complex SQL.</p>
<p>This is an advantage usually for a couple reasons. First, by processing all rows at once instead of looping through them one at a time, it&#8217;s generally faster. Second, cursors can make some issues more complex to debug</p>
<h3>MySQL Cursor Sample Code</h3>
<p>Here&#8217;s an example of how to create a MySQL stored procedure that uses a cursor.</p>
<p>I &#8216;over-commented&#8217; the procedure a bit (if there is such a thing!), but I wanted the code to be relatively self-explanatory for people who just cut/paste it.</p>
<p>The SQL required to setup the tables and data follows the example. Everything runs and is tested. It requires MySQL 5.0 or above since before that there was no support for stored procedures.</p>
<p>First, here&#8217;s the sample code. I&#8217;ll follow after with some explanation.</p>
<pre>/*
 *      Procedure Name  :  usp_cursor_example
 *      Database/Schema :  foo
 *
 *      Description:
 *          An example of a MySQL stored procedure that uses a cursor
 *
 *
 *      Tables Impacted :
 *         foo.friend_status - read-only
 *         DDL? - None
 *         DML? - Only Selects
 *
 *      Params:
 *         name_in - the name of the friend to search for
 *
 *      Revision History:
 *
 *         Date:          Id:        Comment:
 *         2009/03/01     kbedell    Original
 *
 *    Copyright (c) 2009 Kevin Bedell
 *    Can be resused under terms of the 'MIT license'.
 *
 *    To test:
 *      - Multiple records: call foo.usp_cursor_example('John');
 *      - One record:       call foo.usp_cursor_example('Julie');
 *      - Zero records:     call foo.usp_cursor_example('Waldo');
 *
 */
DROP PROCEDURE IF EXISTS  `foo`.`usp_cursor_example`;
DELIMITER $$
CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`.`usp_cursor_example`(
  IN name_in VARCHAR(255)
)
READS SQL DATA
BEGIN

  /*
    All 'DECLARE' statements must come first
  */

  -- Declare '_val' variables to read in each record from the cursor
  DECLARE name_val VARCHAR(255);
  DECLARE status_update_val VARCHAR(255);

  -- Declare variables used just for cursor and loop control
  DECLARE no_more_rows BOOLEAN;
  DECLARE loop_cntr INT DEFAULT 0;
  DECLARE num_rows INT DEFAULT 0;

  -- Declare the cursor
  DECLARE friends_cur CURSOR FOR
    SELECT
        name
      , status_update
    FROM foo.friend_status
    WHERE name = name_in;

  -- Declare 'handlers' for exceptions
  DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET no_more_rows = TRUE;

  /*
    Now the programming logic
  */

  -- 'open' the cursor and capture the number of rows returned
  -- (the 'select' gets invoked when the cursor is 'opened')
  OPEN friends_cur;
  select FOUND_ROWS() into num_rows;

  the_loop: LOOP

    FETCH  friends_cur
    INTO   name_val
    ,      status_update_val;

    -- break out of the loop if
      -- 1) there were no records, or
      -- 2) we've processed them all
    IF no_more_rows THEN
        CLOSE friends_cur;
        LEAVE the_loop;
    END IF;

    -- the equivalent of a 'print statement' in a stored procedure
    -- it simply displays output for each loop
    select name_val, status_update_val;

    -- count the number of times looped
    SET loop_cntr = loop_cntr + 1;

  END LOOP the_loop;

  -- 'print' the output so we can see they are the same
  select num_rows, loop_cntr;

END
DELIMITER ;</pre>
<h3>Discussion and Explanation of the MySQL Cursor Example Code</h3>
<h4>The &#8216;Declaration&#8217; section</h4>
<p>Before any actual programming logic starts, you need to first list all &#8216;declarations&#8217;. This is a requirement of MySQL.</p>
<p>Here&#8217;s the declaration section:</p>
<pre>  /*
    All 'DECLARE' statements must come first
  */

  -- Declare '_val' variables to read in each record from the cursor
  DECLARE name_val VARCHAR(255);
  DECLARE status_update_val VARCHAR(255);

  -- Declare variables used just for cursor and loop control
  DECLARE no_more_rows BOOLEAN;
  DECLARE loop_cntr INT DEFAULT 0;
  DECLARE num_rows INT DEFAULT 0;

  -- Declare the cursor
  DECLARE friends_cur CURSOR FOR
    SELECT
        name
      , status_update
    FROM foo.friend_status
    WHERE name = name_in;

  -- Declare 'handlers' for exceptions
  DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET no_more_rows = TRUE;</pre>
<p>There are 4 sections to the declaration section:</p>
<ul>
<li>Declaration of one variable to hold the &#8216;value&#8217; of each column in the result of the query.</li>
</ul>
<p style="padding-left: 30px;">Here, I recommend simply naming each variable by adding &#8216;_val&#8217; to the end of the actual returned column name. Also, make sure the types match!</p>
<ul>
<li>Declaration of variables that are used for counting rows and controlling looping.</li>
</ul>
<p style="padding-left: 30px;">Generally, every stored procedure that uses a cursor can always simply have the same set.</p>
<p style="padding-left: 30px;">In this example we have three variables &#8212; a boolean that gets set if we try to read from the cursor when no data is left, and two counters for the number of rows processed (we have two here because the example demonstrates two different methods of counting rows processed &#8212; use either of them).</p>
<ul>
<li>Declaration of the actual query that will generate the result set to be held by the cursor</li>
</ul>
<p style="padding-left: 30px;">The query is not actually invoked until later in the procedure where the cursor is &#8216;opened&#8217;. Also, in this example you can see that the cursor uses a variable in its &#8216;where clause&#8217; that is passed in as an argument to the procedure.</p>
<ul>
<li>Declaration of &#8216;handlers&#8217; to control execution. These are usually always the same.</li>
</ul>
<p style="padding-left: 30px;">This is a standard declaration that sets up processing for when the cursor contains no (or no more) rows.</p>
<h4>Opening the cursor and finding the number of rows returned</h4>
<p>The next step is to &#8216;open&#8217; the cursor. This is where the actual query in the cursor is run &#8211; and one of the places where cursor programming can get tricky.</p>
<pre>  -- 'open' the cursor and capture the number of rows returned
  -- (the 'select' gets invoked when the cursor is 'opened')
  OPEN friends_cur;
  select FOUND_ROWS() into num_rows;</pre>
<p>Notice that we select FOUND_ROWS() into our num_rows variable directly after we open the cursor. The FOUND_ROWS() &#8216;information function&#8217; contains the number of rows found in the last select statement run.</p>
<p>If the query fails or errors for some reason, the &#8216;open&#8217; call will fail &#8212; and it can fail &#8216;silently&#8217;. This is one of the issues with cursors &#8212; you need to make sure that your queries work and are solid.</p>
<p>You also need to make sure that they are tolerant to data changing over time. Make sure that if the underlying data in the table changes over time, your query will still work.</p>
<h4>Looping through the cursor result set</h4>
<p>There are multiple methods for looping in MySQL &#8212; I use this method and recommend that you just cut/paste this code for every cursor you write. This method works and you won&#8217;t have to think about it.</p>
<pre>  the_loop: LOOP

    FETCH  friends_cur
    INTO   name_val
    ,      status_update_val;

    -- break out of the loop if
      -- 1) there were no records, or
      -- 2) we've processed them all
    IF no_more_rows THEN
        CLOSE friends_cur;
        LEAVE the_loop;
    END IF;

    -- the equivalent of a 'print statement' in a stored procedure
    -- it simply displays output for each loop
    select name_val, status_update_val;

    -- count the number of times looped
    SET loop_cntr = loop_cntr + 1;

  END LOOP the_loop;</pre>
<p>There are a couple things to point out here.</p>
<p>First, note that the <em>no_more_rows</em> variable gets set automatically when you &#8216;FETCH&#8217; from the cursor. For this reason you should always test for that condition immediately after you try to read a row.</p>
<p>Note that we have a counter in the loop here as well. This is just another way to count the rows processed. Use what works for you.</p>
<h4>Conclusion</h4>
<p>In this post, we gave some sample code that can be used/reused to create MySQL Stored Procedures containing a cursor. Best of luck with the code and feel free to post comments below if you find any problems or if you have any suggestions!</p>
<h4>Setup code for the sample MySQL Stored Procedure with a Cursor</h4>
<p>Here is the setup SQL I used to create the tables/data you need to test the stored procedure and cursor.</p>
<pre>/*
 *      Procedure/File Name  :  ex1_setup.sql
 *      Database/Schema      :  foo
 *
 *      Description:
 *          Setup file to support simple cursor example
 *
 *      Tables Impacted :
 *         foo.friend_status - drop/re-create table and populate.
 *
 *      Params:
 *         None.
 *
 *      Revision History:
 *
 *         Date:          Id:        Comment:
 *         2009/03/01     kbedell    Original
 *
 *    Copyright (c) 2009 Kevin Bedell
 *    Can be resused under terms of the 'MIT license'.
 *
 *    To test:
 *      - Run script then: select * from foo.friend_status;
 *
 */
drop table if exists foo.friend_status; 

CREATE TABLE IF NOT EXISTS `foo`.`friend_status` (
    `id`            INTEGER(10) unsigned NOT NULL auto_increment,
    `name`          VARCHAR(255) NOT NULL,
    `status_update` VARCHAR(255) NOT NULL,
    PRIMARY KEY (`id`)
);

insert into foo.friend_status
    (name, status_update)
  values
      ('John',  'Woke up. Guiness for Brkfst.')
    , ('Fred',  'is thinking about joining the circus')
    , ('Erin',  "Getting ready for a job interview")
    , ('Amy',   'at work and dreaming of kittens')
    , ('John',  'Watching Scooby Doo reruns. Guiness for Lunch.')
    , ('Amy',   'dreaming of fuzzy slippers and wedding dresses')
    , ('Julie', 'is hating working two jobs')
    , ('John',  'Out of the shower finally. Guiness for Dinner.')
    , ('Erin',  "if I don't get this job, I'll be asking 'Paper or Plastic?'")
    , ('Amy',   'dreaming of Meeting Mr. Right!')
    , ('Erin',  'Nailed the job interview -- calling John to celebrate!')
    , ('Amy',   'John called -- meeting him at the pub!')
    , ('John',  'Heading out to meet friends for some Guiness!')
;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kbedell.com/2009/03/02/a-simple-example-of-a-mysql-stored-procedure-that-uses-a-cursor/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
	</channel>
</rss>

