CPSC-110 Spring 2009
Lab 9
Thursday, April 9, 2009
Professor Heidi Ellis

Be sure that the professor or TA checks off your work before leaving!!!

Objectives:

In this lab we will write and execute stored procedures in MySQL that use variables to hold data for the duration of the procedure and looping statements. We will once again be working with our police database.

Variables

There are times when you want to store a value for the duration of a stored procedure, for instance, the total of two numbers. A variable is used to hold such a value in a stored procedure. Variables must adhere to the following rules:
  1. Variables are defined using the DECLARE statement.
  2. Variable names must follow the naming conventions for SQL columns (e.g., no spaces or non-alphanumeric characters except for the underscore, variable names must be unique, etc.).
  3. Variables must be declared to be of an SQL type.
  4. A value is assigned to a variable using the SET keyword.
  5. Within a procedure, once a variable has been set to hold a value, the variable will hold that value until the end of the procedure or until the variable is provided a new value with another SET.
Below is an example of a short procedure that contains three variables. All three variables are of type INT The two variables named firstValue and secondValue are set to be literal values of 5 and 10. The total variable is set to be the result of the values held in variables firstValue and secondValue together. The lines that begin with the double dashes (--) are comments. Comments are intended to document what the code does and are not executed by the system. You should use comments liberally to explain what your code does.
CREATE PROCEDURE `police`.`variable` ()
BEGIN
  DECLARE firstValue INT;  -- Variable of type integer to hold the first number
  DECLARE secondValue INT; -- Variable of type integer to hold the second number
  DECLARE total INT;       -- Variable to hold the total

  SET firstValue = 5;
  SET secondValue = 10;
  SET total = firstValue + secondValue;     -- Add firstValue and secondValue together
  select concat("The total is: ", total);   -- Display the total
END $$
The concat statement concatenates two different elements into the output statement. In this case, it combines the string "The total is:" with the value contained in the total variable. The resulting output looks like:

The charvariable procedure shown below demonstrates the use of variables of type VARCHAR. The procedure has two variables, fname which is set to the string "Heidi", and lname which is set to the string "Ellis". The select statement prints the string: "Full name: HeidiEllis". How would we get a space between the first and last names?
CREATE PROCEDURE `police`.`charvariable` ()
BEGIN
  DECLARE fname VARCHAR(20);    -- Variable to hold first name
  DECLARE lname VARCHAR(20);    -- Variable to hold last name

  SET fname = "Heidi";
  SET lname = "Ellis";
  select concat("Full name: ", fname, lname);
END $$

Try it on your own

Pair Programming:
  1. Locate your partner and introduce yourself:
  2. Abby AldermanPreston Maddock
    Cory DiBenedettoAndrea Titone
    Briggs ElwellRichard Curtin
    Whitney MerrillElise Galbo
    Ryan PiacentiniBrooke Haynes
    Matt VibertBrenna Fox
    Robert PerrymanShanice Smith
    Ben McDanielAlyssa Cockrell
  3. Select one person's account in which to work.
  4. Select one person to start as "driver". Change driver for each new procedure created.
  5. Using KWrite (or another text editor), create a new file called lab9.txt. Put both team members' names in the document.
  6. Copy the procedure code for each procedure created into the lab9.txt file.
  7. Email the completed file to the partner in whose account you were not working so that they have a copy.
  8. Print the lab9.txt file and hand it in at the end of lab.
Write a procedure that sets three numbers and then prints the average of the three numbers. How many variables did you declare?

Looping

One thing that you may frequently want to do in a stored procedure is to repeat one or more steps over and over again. For instance, you may want to step through each row returned by a select statement or to count something. This is supported in MySQL by the loop construct. Loops allow you to enclose a sequence of code within a loop and that sequence of code will be executed repeatedly until some exit condition is met. MySQL supports three kinds of looping constructs: LOOP, REPEAT, and WHILE. We will start by looking at the LOOP construct.

The LOOP construct identifies a block of SQL code that will be executed one or more times. A few comments: The syntax for a LOOP statement is:
thelabel: LOOP
  -- Put code that is to be repeated here
END LOOP thelabel;
Note that the loop above will executed infinitely. Why? Because the loop has no LEAVE statement. LEAVE statements are associated with an if statement that tests whether an exit condition is true or not. In other words, all loops need an exit condition that is checked in order for the system to determine when to stop iterating through a loop. Note the use of indentation to make the code more readable.
thelabel: LOOP
  -- Put code that is to be repeated here
  if (exit condition)
     then LEAVE thelabel;
  end if;
END LOOP thelabel;
The printFive procedure below adds one to a variable i five times using a loop. I have added comments to describe how the loop works.
-- This procedure adds one to a counter variable five times and then prints the contents of the variable
CREATE PROCEDURE `printFive`()
BEGIN

DECLARE i INT;      -- Variable to hold the running total
SET i = 0;          -- Initialize the variable to zero before entering loop

helloloop: LOOP               -- Beginning of loop
  SET i = i + 1;              -- Increment loop counter
  if (i = 5)                  -- Check to see if loop counter has reached maximum value (5) 
     then LEAVE helloloop;    -- If so, exit the loop (go to "end LOOP helloloop")
  end if;                     -- Otherwise end the if statement and go back to line "helloloop: LOOP" and repeat
end LOOP helloloop;           -- End the loop 

  select i;                   -- Print the total 
END$$
In the example above, the exit condition is the statement if (i = 5) followed by the then LEAVE helloloop;. In order to exit the loop, the statements within the loop must ensure that the exit condition will become true. In the example above, this is done by starting the looping variable i at some value less than five outside of the loop and then incrementing i by one each iteration through the loop. In this manner, the value contained in i gradually approaches and then fulfills the exit condition of i = 5.

Now lets look at how we would total up the numbers from one to five. (E.g., 1 + 2 + 3 + 4 + 5) We will again use a loop and again the variable i will be used to keep track the number of times the loop is executed. A new variable, j will keep the running total of the numbers as they are totaled. In other words, we will add the contents of i to the contents of j each time the loop is executed.
-- This procedure totals the numbers between one and five
-- E.g., 1 + 2 + 3 + 4 + 5
CREATE PROCEDURE `police`.`totalUpToFive` ()
BEGIN
  DECLARE i, j INT;      -- Two variables to hold the number of times
                         -- through the loop and the running total
  SET i = 1;             -- Variable to hold the number of times to loop
  SET j = 1;             -- Variable to hold the running total. 
  
  myloop: LOOP           -- Start the loop
      SET j = j + i;     -- Add the loop counter to the running total
      SET i = i + 1;     -- Increment the loop counter

      If i = 5           -- Check to see if the maximum number of iterations has been reached
         then LEAVE myloop;             -- If so, leave the loop
     end if;

  end LOOP myloop;       -- End the loop
  select j;              -- Display the results 

END$$
Note how the code above is indented. The contents of the stored procedure between the BEGIN and END are indented several spaces. In addition, the contents of the loop are indented a few more spaces and the then portion of the looping exit condition are indented even a few more. This is called "nesting" and increases the readability of the code. Also note that the comment groups begin at the same place on the line.

You try it: Given the totalUpToFive code above, draw the table that shows the values for i and j for all iterations of the loop. Create the totalUpToFive procedure as above. Modify so that it totals up to six. What did you change? Be sure to nest and comment your code appropriately.

Now that we can total the values of numbers one through five, how would we total the values of numbers from one to some other value? Yes, you guessed it, you would use a parameter. The totalUpTo procedure shown below is provided a parameter m. This parameter is used in place of the 5 in the exit condition of the loop:
- This procedure totals the numbers up to some maximum m
-- E.g., 1 + 2 + 3 + 4 + 5
CREATE PROCEDURE `police`.`totalUpTo` (m INT)
BEGIN
  DECLARE i, j INT;      -- Two variables to hold the number of times
                         -- through the loop and the running total
  SET i = 1;             -- Variable to hold the number of times to loop
  SET j = 1;             -- Variable to hold the running total. 
  
  myloop: LOOP           -- Start the loop
      SET j = j + i;     -- Add the loop counter to the running total
      SET i = i + 1;     -- Increment the loop counter

      If i = m           -- Check to see if the maximum number of iterations has been reached
         then LEAVE myloop;             -- If so, leave the loop
     end if;

  end LOOP myloop;       -- End the loop
  select j;              -- Display the results 
END$$
You try it: Create the totalUpTo procedure as above. Execute the procedure several times providing different input values. What happens if you enter a negative number? Why does this happen?

Try it on your own

Now write stored procedures for the items below. Copy the procedures into a separate file and hand in at the end of class.
  1. Create a procedure called countDown that counts down from five to zero. Print the value of the looping variable after leaving the loop.
  2. Now modify the countDown procedure to count down from any number by adding a parameter to the procedure.
  3. Now modify the countDown procedure to count how many times the loop is executed. This will require adding a variable to the procedure. Instead of printing the value of the looping variable, print the number of times the loop was executed.
  4. If you have time: Create a procedure called multiply that is passed two INT parameters x and y. Use a loop to calculate the multiplication of x and y. Remember that multiplication can be thought of as the process of adding one number, say x, to itself y times. Therefore, the actual calculation should use a loop to add x to a total y times. In other words, your loop should exit when the counting variable is greater than y and you should add x to a variable that keeps track of the total within the loop. Don't forget to declare all variables and to initialize all variables via the SET keyword.

You're done!! Be sure to have the professor or TA check off your work before you leave!!