• Tidak ada hasil yang ditemukan

The CASE Statement

Dalam dokumen Book MySQL Stored Procedure Programming (Halaman 114-118)

In this case, the constant repetition of the sale_value condition and the free_

shippingcall actually undermines the readability of our logic—as well as imposing a performance overhead (see Chapter 22). It might be better to use a nestedIFstruc- ture that makes it clear that everyone gets free shipping for orders over $200, and that discounts are then applied based on the customer loyalty status only.

Example 4-14 shows the nestedIF implementation.

Simple CASE statement

CASE statements can take two forms. The first—sometimes referred to as asimple CASE statement—compares the output of an expression with multiple conditions:

CASE expression WHEN value THEN

statements [WHEN value THEN

statements ...]

[ELSE

statements]

END CASE;

This syntax is useful when we are checking the output of some expression against a set of distinct values. For instance, we could check the customer loyalty status from our previous example using the simpleCASE statement shown in Example 4-15.

As with theIFcommand, you can specify multipleWHENstatements and you can spec- ify anELSE clause that executes if none of the other conditions apply.

However, it is critical to realize that aCASEstatement will raise an exception if none of the conditions apply. This means that in Example 4-15 if thecustomer_statuswas not one of 'PLATINUM', 'GOLD', 'SILVER', or 'BRONZE' then the following runtime excep- tion would occur:

ERROR 1339 (20000): Case not found for CASE statement

We could create an exception handler to cause this error to be ignored (as described in Chapter 6), but it is probably better practice to code anELSEclause to ensure that all possible conditions are handled. So, we should probably adapt the previous example to include anELSE clause that applies a zero discount to a customer who meets none of the preceding conditions.

Example 4-15. Example of a simple CASE statement CASE customer_status

WHEN 'PLATINUM' THEN

CALL apply_discount(sale_id,20); /* 20% discount */

WHEN 'GOLD' THEN

CALL apply_discount(sale_id,15); /* 15% discount */

WHEN 'SILVER' THEN

CALL apply_discount(sale_id,10); /* 10% discount */

WHEN 'BRONZE' THEN

CALL apply_discount(sale_id,5); /* 5% discount*/

END CASE;

If none of theCASEstatements matches the input condition,CASEwill raise MySQL error 1339. You should either construct an error handler to ignore this error, or ensure that the exception never occurs by including anELSE clause in yourCASE statement.

The simpleCASEstatement is useful when comparing the value of an expression to a series of specific values. However, the simpleCASEstatement cannot easily or natu- rally match ranges, or handle more complex conditions involving multiple expres- sions. For these more complex “cases” we can use a “searched” CASE statement, described in the next section.

“Searched” CASE statement

ThesearchedCASEstatement is functionally equivalent to an IF-ELSEIF-ELSE-END IF block. The searchedCASE statement has the following syntax:

CASE

WHEN condition THEN statements [WHEN condition THEN

statements...]

[ELSE

statements]

END CASE;

Using the searchedCASEstructure, we can implement the free shipping and discount logic that we implemented earlier usingIF. A direct translation of our sales discount and free shipping logic using a searchedCASE statement is shown in Example 4-16.

Example 4-16. Example of a searched CASE statement CASE

WHEN (sale_value >200 AND customer_status='PLATINUM') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,20); /* 20% discount */

WHEN (sale_value >200 AND customer_status='GOLD') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,15); /* 15% discount */

WHEN (sale_value >200 AND customer_status='SILVER') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,10); /* 10% discount */

WHEN (sale_value >200 AND customer_status='BRONZE') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,5); /* 5% discount*/

WHEN (sale_value>200) THEN

However, remember that if none of the WHEREclauses is matched, a 1339 error will occur. Therefore, this code will cause a fatal error if the order is less than $200 or the customer is not in our loyalty program—not a happy outcome. So we should protect our code—and our job security—by including an ELSE clause as shown in Example 4-17.

Note that because MySQL lacks a NULL (do nothing) statement in the stored pro- gram language, we had to add a dummy statement—but this statement has negligi- ble overhead.

As with our IF implementation of this logic, we could also use nested CASE state- ments to perform the same logic with arguably greater clarity. In Example 4-18 we combine simple and searchedCASEstatements, and also include a “not found” han- dler to avoid having to include ELSE statements. We enclose the entire thing in a block so that our handler does not inadvertently influence other statements within the stored program.

CALL free_shipping(sale_id); /* Free shipping*/

END CASE;

Example 4-17. Adding a dummy ELSE clause to our searched CASE example CASE

WHEN (sale_value >200 AND customer_status='PLATINUM') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,20); /* 20% discount */

WHEN (sale_value >200 AND customer_status='GOLD') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,15); /* 15% discount */

WHEN (sale_value >200 AND customer_status='SILVER') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,10); /* 10% discount */

WHEN (sale_value >200 AND customer_status='BRONZE') THEN CALL free_shipping(sale_id); /* Free shipping*/

CALL apply_discount(sale_id,5); /* 5% discount*/

WHEN (sale_value>200) THEN

CALL free_shipping(sale_id); /* Free shipping*/

ELSE

SET dummy=dummy;

END CASE;

Example 4-16. Example of a searched CASE statement (continued)

Dalam dokumen Book MySQL Stored Procedure Programming (Halaman 114-118)