7. Stored Procedures
Stored functions, stored procedures, and events are known by the common
name stored routines. Since the server
treats stored procedures and stored functions very differently, stored procedures will
be covered in this section and stored functions in the next section.
The situation for stored routines is similar to triggers in some
aspects, but very different in others. Like triggers, stored routines
offer a DEFINER clause, and it
must be explicitly added to the binary log whether or not the statement
includes it. But the invocation of stored routines is handled
differently from triggers.
To begin, let’s extend Example 3-6, which defines
tables for employees and logs, with some utility routines to work with
the employees. Even though this can be handled with standard INSERT, DELETE, and UPDATE statements, we’ll used stored
procedures to demonstrate some issues involved in writing them to the
binary log. For these purposes, let’s extend the example with the
functions in Example 9
for adding and removing employees.
Example 9. Stored procedure definitions for managing employees
delimiter $$
CREATE PROCEDURE employee_add(p_name CHAR(64), p_email CHAR(64),
p_password CHAR(64))
MODIFIES SQL DATA
BEGIN
DECLARE pass CHAR(64);
SET pass = PASSWORD(p_pass)
INSERT INTO employee(name, email, password)
VALUES (p_name, p_email, pass);
END $$
CREATE PROCEDURE employee_passwd(p_email CHAR(64), p_password CHAR(64))
MODIFIES SQL DATA
BEGIN
DECLARE pass CHAR(64);
SET pass = PASSWORD(p_password)
UPDATE employee SET password = pass WHERE email = p_email;
END $$
CREATE PROCEDURE employee_del(p_name CHAR(64))
MODIFIES SQL DATA
BEGIN
DELETE FROM employee WHERE name = p_name;
END $$
delimiter ;
|
For the employee_add and
employee_passwd procedures, we have
extracted the encrypted password into a separate variable for the
reasons already explained, but the employee_del procedure just contains a
DELETE statement, since nothing else
is needed. A binlog entry corresponding to one function is:
master> SHOW BINLOG EVENTS FROM 97911 LIMIT 1\G
*************************** 1. row ***************************
Log_name: master-bin.000038
Pos: 97911
Event_type: Query
Server_id: 1
End_log_pos: 98275
Info: use `test`; CREATE DEFINER=`root`@`localhost`PROCEDURE ...
1 row in set (0.00 sec)
As expected, the definition of this procedure is extended with
the DEFINER clause before
writing the definition to the binary log, but apart from that, the body
of the procedure is left intact. Notice that the CREATE PROCEDURE
statement is replicated as a Query
event, as are all DDL statements.
In this regard, stored routines are similar to triggers in the way
they are treated by the binary log. But invocation differs significantly
from triggers. Example 10 calls the
procedure that adds an employee and shows the resulting contents of the
binary log.
Example 10. Calling a stored procedure
master> CALL employee_add('chuck', '[email protected]', 'abrakadabra');
Query OK, 1 row affected (0.00 sec)
master> SHOW BINLOG EVENTS FROM 104033\G
*************************** 1. row ***************************
Log_name: master-bin.000038
Pos: 104033
Event_type: Intvar
Server_id: 1
End_log_pos: 104061
Info: INSERT_ID=1
*************************** 2. row ***************************
Log_name: master-bin.000038
Pos: 104061
Event_type: Query
Server_id: 1
End_log_pos: 104416
Info: use `test`; INSERT INTO employee(name, email, password)
VALUES ( NAME_CONST('p_name',_latin1'chuck' COLLATE 'latin1_swedish_ci'),
NAME_CONST('p_email',_latin1'[email protected]' COLLATE 'latin1_swedish_ci'),
NAME_CONST('pass',_latin1'*FEB349C4FDAA307A...' COLLATE 'latin1_swedish_ci'))
2 rows in set (0.00 sec)
|
In Example 10, there are four
things that you should note:
The CALL statement is
not written to the binary log. Instead, the statements
executed as a result of the call are written to
the binary log. In other words, the body of the stored procedure is
unrolled into the binary log.
The statement is rewritten to not contain any references to
the parameters of the stored procedure—that is, p_name, p_email, and p_password. Instead, the NAME_CONST
function is used for each parameter to create a result set with a
single value.
The locally declared variable pass is also replaced with a NAME_CONST expression, where the second
parameter contains the encrypted password.
Just as when a statement that invokes a trigger is written to
the binary log, the statement that calls the stored procedure is
preceded by an Intvar event
holding the insert ID used when adding the employee to the
log table.
Since neither the parameter names nor the locally declared names
are available outside the stored routine, NAME_CONST is used to associate the name of
the parameter or local variable with the constant value used when
executing the function. This guarantees that the value can be used in
the same way as the parameter or local variable. However, this change is
not significant; currently it offers no advantages over using the
parameters directly.