Beginning PHP and MySQL From Novice to Professional phần 9 pps

108 302 0
Beginning PHP and MySQL From Novice to Professional phần 9 pps

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

830 CHAPTER 32 ■ STORED ROUTINES You may be wondering about the DELIMITER statement, though. By default, MySQL uses the semicolon to determine when a statement has concluded. However, when creating a multistatement stored routine, you need to write several statements, but you don’t want MySQL to do anything until you’ve finished writing the stored routine. Therefore, you must change the delimiter to another character string. It doesn’t have to be //. You can choose whatever you please, ||| or ^^, for instance. Executing a Stored Routine Executing a stored routine is accomplished by referencing the stored routine in conjunction with the CALL statement. For example, executing the previously created get_inventory procedure is accomplished like so: mysql>CALL get_inventory(@inv); mysql>SELECT @inv; Executing get_inventory will return: + + | @inv | + + | 45 | + + Creating and Using Multistatement Stored Routines Single-statement stored routines are quite useful, but stored routines’ real power lies in their ability to encapsulate and execute several statements. In fact, an entire language is at your disposal, enabling you to perform rather complex tasks such as conditional evaluation and iteration. For instance, suppose your company’s revenues are driven by a sales staff. To coax the staff into meeting its lofty goals, bonuses are tacked onto their monthly paychecks, with the size of the bonus proportional to the revenues attributed to the employee. The company handles its payroll internally, using a custom Java program to calculate and print the bonus checks at the conclusion of each year; Gilmore_862-8C32.fm Page 830 Friday, February 15, 2008 7:34 AM CHAPTER 32 ■ STORED ROUTINES 831 however, a Web-based interface is provided to the sales staff so that it can monitor its progress (and bonus size) in real time. Because both applications would require the ability to calculate the bonus amount, this task seems like an ideal candidate for a stored function. The syntax for creating this stored function looks like this: DELIMITER // CREATE FUNCTION calculate_bonus (emp_id CHAR(8)) RETURNS DECIMAL(10,2) COMMENT 'Calculate employee bonus' BEGIN DECLARE total DECIMAL(10,2); DECLARE bonus DECIMAL(10,2); SELECT SUM(revenue) INTO total FROM sales WHERE employee_id = emp_id; SET bonus = total * .05; RETURN bonus; END; // DELIMITER ; The calculate_bonus function would then be called like this: mysql>SELECT calculate_bonus("35558ZHU"); This function returns something similar to this: + + | calculate_bonus("35558ZHU") | + + | 295.02 | + + Even though this example includes some new syntax (all of which will soon be introduced), it should be rather straightforward. The remainder of this section is devoted to coverage of the syntax commonly used when creating multistatement stored routines. Gilmore_862-8C32.fm Page 831 Friday, February 15, 2008 7:34 AM 832 CHAPTER 32 ■ STORED ROUTINES EFFECTIVE STORED ROUTINE MANAGEMENT Stored routines can quickly become lengthy and complex, adding to the time required to create and debug their syntax. For instance, typing in the calculate_bonus procedure can be tedious, partic- ularly if along the way you introduced a syntax error that required the entire routine to be entered anew. To alleviate some of the tedium, insert the stored routine creation syntax into a text file, and then read that file into the mysql client, like so: %>mysql [options] < calculate_bonus.sql The [options] string is a placeholder for your connection variables. Don’t forget to change over to the appropriate database before creating the routine, by adding USE db_name; to the top of the script; otherwise, an error will occur. To modify an existing routine, you can change the file as necessary, delete the existing routine by using DROP PROCEDURE (introduced later in this chapter), and then re-create it using the above process. While there is an ALTER PROCEDURE statement (also introduced later in this chapter), it is presently only capable of modifying routine characteristics. Another very effective mechanism for managing routines is through MySQL Query Browser, introduced in Chapter 27. Via the interface you can create, edit, and delete routines. The BEGIN and END Block When creating multistatement stored routines, you need to enclose the statements in a BEGIN/END block. The block prototype looks like this: BEGIN statement 1; statement 2; statement N; END Note that each statement in the block must end with a semicolon. Conditionals Basing task execution on run-time information is key for wielding tight control over its outcome. Stored routine syntax offers two well-known constructs for performing conditional evaluation: the IF-ELSEIF-ELSE statement and the CASE statement. Both are introduced in this section. Gilmore_862-8C32.fm Page 832 Friday, February 15, 2008 7:34 AM CHAPTER 32 ■ STORED ROUTINES 833 IF-ELSEIF-ELSE The IF-ELSEIF-ELSE statement is one of the most common means for evaluating conditional statements. In fact, even if you’re a novice programmer, you’ve likely already used it on numerous occasions. Therefore, this introduction should be quite familiar. The prototype looks like this: IF condition THEN statement_list [ELSEIF condition THEN statement_list] . . . [ELSE statement_list] END IF For example, suppose you modified the previously created calculate_bonus stored procedure to determine the bonus percentage based on not only sales but also the number of years the salesperson has been employed at the company: IF years_employed < 5 THEN SET bonus = total * .05; ELSEIF years_employed >= 5 and years_employed < 10 THEN SET bonus = total * .06; ELSEIF years_employed >=10 THEN SET bonus = total * .07; END IF CASE The CASE statement is useful when you need to compare a value against an array of possibilities. While doing so is certainly possible using an IF statement, the code readability improves considerably by using the CASE statement. Its prototype looks like this: CASE WHEN condition THEN statement_list [WHEN condition THEN statement_list] . . . [ELSE statement_list] END CASE Consider the following example, which sets a variable containing the appropriate sales tax rate by comparing a customer’s state to a list of values: Gilmore_862-8C32.fm Page 833 Friday, February 15, 2008 7:34 AM 834 CHAPTER 32 ■ STORED ROUTINES CASE WHEN state="AL" THEN: SET tax_rate = .04; WHEN state="AK" THEN: SET tax_rate = .00; WHEN state="WY" THEN: SET tax_rate = .04; END CASE; Alternatively, you can save some typing by using the following variation: CASE state WHEN "AL" THEN: SET tax_rate = .04; WHEN "AK" THEN: SET tax_rate = .00; WHEN "WY" THEN: SET tax_rate = .04; END CASE; Iteration Some tasks, such as inserting a number of new rows into a table, require the ability to repeatedly execute over a set of statements. This section introduces the various methods available for iterating and exiting loops. ITERATE Executing the ITERATE statement causes the LOOP, REPEAT, or WHILE block within which it’s embedded to return to the top and execute again. Its prototype looks like this: ITERATE label Consider an example. The following stored procedure will increase every employee’s salary by 5 percent, except for those assigned the employee category of 0: DELIMITER // DROP PROCEDURE IF EXISTS `corporate`.`calc_bonus`// Gilmore_862-8C32.fm Page 834 Friday, February 15, 2008 7:34 AM CHAPTER 32 ■ STORED ROUTINES 835 CREATE PROCEDURE `corporate`.`calc_bonus` () BEGIN DECLARE empID INT; DECLARE emp_cat INT; DECLARE sal DECIMAL(8,2); DECLARE finished INTEGER DEFAULT 0; DECLARE emp_cur CURSOR FOR SELECT employee_id, salary FROM employees ORDER BY employee_id; DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished=1; OPEN emp_cur; calcloop: LOOP FETCH emp_cur INTO empID, emp_cat, sal; IF finished=1 THEN LEAVE calcloop; END IF; IF emp_cat=0 THEN ITERATE calcloop; END IF; UPDATE employees SET salary = sal + sal * 0.05 WHERE employee_id=empID; END LOOP calcloop; CLOSE emp_cur; END// DELIMITER ; You might have noticed that in this example a cursor was used to iterate through each row of the result set. If you’re not familiar with this feature, see Chapter 35. Gilmore_862-8C32.fm Page 835 Friday, February 15, 2008 7:34 AM 836 CHAPTER 32 ■ STORED ROUTINES LEAVE Pending the value of a variable or outcome of a particular task, you may want to immediately exit a loop or a BEGIN/END block by using the LEAVE command. Its proto- type follows: LEAVE label An example of LEAVE in action is provided in the introduction to LOOP, next. You’ll also find an example in the previous example. LOOP The LOOP statement will continue iterating over a set of statements defined in its block until the LEAVE statement is encountered. Its prototype follows: [begin_label:] LOOP statement_list END LOOP [end_label] MySQL stored routines are unable to accept arrays as input parameters, but you can mimic the behavior by passing in and parsing a delimited string. For example, suppose you provide clients with an interface for choosing among an array of ten corporate services they’d like to learn more about. The interface might be presented as a multiple-select box, checkboxes, or some other mechanism; which one you use is not important, because ultimately the array of values would be condensed into a string (using PHP’s implode() function, for instance) before being passed to the stored routine. For instance, the string might look like this, with each number representing the numerical identifier of a desired service: 1,3,4,7,8,9,10 The stored procedure created to parse this string and insert the values into the database might look like this: DELIMITER // CREATE PROCEDURE service_info (client_id INT, services varchar(20)) BEGIN Gilmore_862-8C32.fm Page 836 Friday, February 15, 2008 7:34 AM CHAPTER 32 ■ STORED ROUTINES 837 DECLARE comma_pos INT; DECLARE current_id INT; svcs: LOOP SET comma_pos = LOCATE(',', services); SET current_id = SUBSTR(services, 1, comma_pos); IF current_id <> 0 THEN SET services = SUBSTR(services, comma_pos+1); ELSE SET current_id = services; END IF; INSERT INTO request_info VALUES(NULL, client_id, current_id); IF comma_pos = 0 OR current_id = '' THEN LEAVE svcs; END IF; END LOOP; END// DELIMITER ; Now call service_info, like so: call service_info("45","1,4,6"); Once executed, the request_info table will contain the following three rows: + + + + | row_id | client_id | service | + + + + | 1 | 45 | 1 | | 2 | 45 | 4 | | 3 | 45 | 6 | + + + + Gilmore_862-8C32.fm Page 837 Friday, February 15, 2008 7:34 AM 838 CHAPTER 32 ■ STORED ROUTINES REPEAT The REPEAT statement operates almost identically to WHILE, looping over a designated statement or set of statements for as long as a certain condition is true. However, unlike WHILE, REPEAT evaluates the conditional after each iteration rather than before, making it akin to PHP’s DO…WHILE construct. Its prototype follows: [begin_label:] REPEAT statement_list UNTIL condition END REPEAT [end_label] For example, suppose you were testing a new set of applications and wanted to build a stored procedure that would fill a table with a given number of test rows. The procedure follows: DELIMITER // CREATE PROCEDURE test_data (rows INT) BEGIN DECLARE val1 FLOAT; DECLARE val2 FLOAT; REPEAT SELECT RAND() INTO val1; SELECT RAND() INTO val2; INSERT INTO analysis VALUES(NULL, val1, val2); SET rows = rows - 1; UNTIL rows = 0 END REPEAT; END// DELIMITER ; Executing this procedure passing in a rows parameter of 5 produces the following result: Gilmore_862-8C32.fm Page 838 Friday, February 15, 2008 7:34 AM [...]... learned how easy it is to incorporate both stored functions and stored procedures into your PHP applications The next chapter introduces another feature new to MySQL 5: triggers 847 Gilmore_862-8C32.fm Page 848 Friday, February 15, 2008 7:34 AM Gilmore_862-8C33.fm Page 8 49 Wednesday, February 27, 2008 9: 04 AM CHAPTER 33 ■■■ MySQL Triggers A trigger is a task that executes in response to some predetermined...Gilmore_862-8C32.fm Page 8 39 Friday, February 15, 2008 7:34 AM CHAPTER 32 ■ STORED ROUTINES + + -+ + | row_id | val1 | val2 | + + -+ + | 1 | 0.06327 89 | 0 .98 0422 | | 2 | 0.712274 | 0.620106 | | | | 3 4 5 | | | 0 .96 3705 | 0 .95 82 09 | 0. 899 9 29 | 0.625017 | 0.425301 | 0.251453 | + + -+ + WHILE The WHILE statement is... produces output similar to the following: EMP12388, Clint Eastwood, Director EMP76777, John Wayne, Actor EMP87824, Miles Davis, Musician Summary This chapter introduced stored routines You learned about the advantages and disadvantages to consider when determining whether this feature should be incorporated into your development strategy, and all about MySQL s specific implementation and syntax Finally,... characteristic of the calculate_bonus method from the default of DEFINER to INVOKER: ALTER PROCEDURE calculate_bonus SQL SECURITY invoker; Deleting a Stored Routine To delete a stored routine, execute the DROP statement Its prototype follows: DROP (PROCEDURE | FUNCTION) [IF EXISTS] sp_name For example, to drop the calculate_bonus stored procedure, execute the following command: mysql> DROP PROCEDURE calculate_bonus;... then discusses MySQL s trigger implementation, showing you how to create, execute, and manage triggers Finally, you’ll learn how to incorporate trigger features into your PHP- driven Web applications Introducing Triggers As developers, we have to remember to implement an extraordinary number of details in order for an application to operate properly Of course, much of the challenge has to do with managing... will execute An introduction to MySQL s trigger implementation was offered, followed by coverage of how to integrate these triggers into your PHP applications The next chapter introduces views, yet another feature new to MySQL 5 861 Gilmore_862-8C33.fm Page 862 Wednesday, February 27, 2008 9: 04 AM Gilmore_862-8C34.fm Page 863 Monday, February 25, 2008 9: 53 AM CHAPTER 34 ■■■ MySQL Views Even relatively... Suppose you are using MySQL to log Apache traffic (say, using the Apache mod_log_sql module) but you also want to create an additional special logging table that tracks just site zone traffic and enables you to quickly tabulate and display the results to an impatient executive Executing this additional insertion can be done automatically with a trigger • Validation: You can use triggers to validate data... Integrating Routines into Web Applications Thus far, all the examples have been demonstrated by way of the MySQL client While this is certainly an efficient means for testing examples, the utility of stored routines is drastically increased by the ability to incorporate them into your application This section demonstrates just how easy it is to integrate stored routines into your PHPdriven Web application... What’s the alternative? After all, queries are essential to the development process, and unless you want to become entangled in managing column-level privileges (see Chapter 29) , it seems you’ll just have to grin and bear it 863 Gilmore_862-8C34.fm Page 864 Monday, February 25, 2008 9: 53 AM 864 CHAPTER 34 ■ MY SQL VIEWS This has long been the case for MySQL users, which is why the addition of a new feature... employee_id, name, position FROM employees ORDER by name; This procedure can then be called from within a PHP script like so: < ?php // Instantiate the mysqli class $db = new mysqli("localhost", "root", "jason", "corporate"); Gilmore_862-8C32.fm Page 847 Friday, February 15, 2008 7:34 AM CHAPTER 32 ■ STORED ROUTINES // Execute the stored procedure $result = $db->query("CALL get_employees()"); // Loop through the . AM CHAPTER 32 ■ STORED ROUTINES 8 39 + + + + | row_id | val1 | val2 | + + + + | 1 | 0.06327 89 | 0 .98 0422 | | 2 | 0.712274 | 0.620106 | | 3 | 0 .96 3705 | 0 .95 82 09 | | 4 | 0. 899 9 29 | 0.625017 | |. routine to be entered anew. To alleviate some of the tedium, insert the stored routine creation syntax into a text file, and then read that file into the mysql client, like so: %> ;mysql [options]. you learned how easy it is to incorporate both stored functions and stored proce- dures into your PHP applications. The next chapter introduces another feature new to MySQL 5: triggers. Gilmore_862-8C32.fm

Ngày đăng: 09/08/2014, 14:21

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan