We’ll illustrate these differences with an example that compares the behavior of the MySQL stored program in non-strict mode with several other programming languages.
Example 3-17 shows a Java program that intends to concatenate an integer value to a string value with the intention of printing the string "99 bottles of beer on the wall". Unfortunately for the beer, the programmer accidentally declared variablecas anint, rather than as aString. The Java compiler detects this error during compile time when it detects an attempt to assign a string expression to an integer variable, and the program fails to compile—no harm done.
Example 3-17. Type checking in a Java program
$cat simplejava.java package simplejava;
public class SimpleJava {
public static void main(String[] args) { String b;
int a;
int c;
a=99;
b="Bottles of beer on the wall";
c=a+" "+c;
System.out.println(c);
Now let’s look at an equivalent example (in a dynamically typed language—in this case, PHP). In PHP and Perl, variable data types change on the fly as required. In Example 3-18, the variable c started as a number, but when subjected to a string assignment, the data type dynamically changed to a string. The program therefore works as required.
Now let’s look at the equivalent non-strict MySQL stored program version of this logic, as shown in Example 3-19. This procedure has the same data type error as in the previous examples—the variable c should be defined as a VARCHAR, but it is instead declared as anINT.
} }
$javac simplejava.java
simplejava.java:11: incompatible types found : java.lang.String
required: int
c=a+" "+c;
^ 1 error
Example 3-18. Dynamic variable typing in PHP
$cat simplephp.php
<?php
$a=99;
$b="Bottles of beer on the wall";
$c=0; #c is a number
$c=$a." ".$b; #c is now a string print $c."\n";
?>
$php simplephp.php
99 Bottles of beer on the wall
Example 3-19. MySQL stored program non-strict type checking CREATE PROCEDURE strict_test( )
BEGIN
DECLARE a INT;
DECLARE b VARCHAR(20);
DECLARE c INT;
SET a=99;
SET b="Bottles of beer on the wall";
SET c=CONCAT(a," ",b);
SELECT c;
END
Example 3-17. Type checking in a Java program (continued)
Without the strict mode, MySQL does not generate an error when the attempt to supply a string to an integer value occurs, nor does it dynamically convert the data type of the integer variables. Instead, it assigns only the numeric part of the string expression to the integer—leading to an unexpected and erroneous result. However, if we had created the procedure when in strict mode, we would have generated a runtime error, as shown in Example 3-20.
It’s almost always preferable for your programs to operate in strict mode. While a non-strict program will sometimes be able to continue where a strict program would fail with an error, the risk that the non-strict program will exhibit unexpected and inappropriate behaviors is usually too high. Remember that the behavior of a stored program depends on the setting of the variablesql_modewhen the program is created, not when the program is run.
Stored programs should almost always operate in strict mode to avoid unpredictable behavior when invalid data assignments occur. The strict mode for a stored program is determined by the setting of the sql_modevariable in effect when the program is created, not when the program is run.
---
Query OK, 0 rows affected (0.01 sec) mysql> CALL strict_test( );
+---+
| C | +---+
| 99 | +---+
1 row in set (0.00 sec)
Query OK, 0 rows affected, 2 warnings (0.00 sec) mysql> SHOW WARNINGS;
+---+---+---+
| Level | Code | Message | +---+---+---+
| Warning | 1265 | Data truncated for column 'b' at row 1 |
| Warning | 1265 | Data truncated for column 'c' at row 1 | +---+---+---+
2 rows in set (0.01 sec)
Example 3-20. Stored program type checking in strict mode mysql> CALL strict_test( );
ERROR 1406 (22001): Data too long for column 'b' at row 1
Example 3-19. MySQL stored program non-strict type checking (continued)
As always, the onus is on the programmer to ensure that data types are used appropri- ately. As Bruce Eckel noted in his article “Strong Typing vs. Strong Testing” (http://
www.mindview.net/WebLog/log-0025), strongtypingin computer languages only pro- vides an illusion of safety—true validation of correct behavior can only be obtained through strongtesting. You should not assume that by declaring a variable as being of a certain type you are implicitly performing validation of the data being applied to that variable.
Conclusion
In this chapter we provided an overview of the building blocks of the MySQL stored program language. The MySQL stored program language—based on the ANSI SQL:
2003 PSM specification—is a block-structured language that supports all the pro- gramming fundamentals that you would expect from a procedural language. The major aspects of the stored program language with which you should be familiar at this point are:
• The DECLARE statement, which allows you to define and initialize program variables.
• Stored program parameters, which allow you to pass information into or—in the case of stored procedures—out of a stored program.
• TheSET statement, which allows you to change the value of a program variable.
• MySQL functions, operators, and data types—the MySQL stored program lan- guage utilizes most of the equivalents available in the MySQL SQL language.
Stored program type checking is very dependent on the setting of thesql_modecon- figuration variable. If a program is created when thesql_modevariable includes one of the strict settings (STRICT_TRANS_TABLESorSTRICT_ALL_TABLES), then the program will reject invalid variable assignments with an error. If neither of the strict modes is in effect, then the stored program will generate an error when invalid data assign- ments occur, but will continue execution. Non-strict stored program behavior can lead to unexpected and subtle bugs, and we recommend that you usually use the strict mode when creating your stored programs.
Chapter 4