A Trigger for Enforcing a Data Constraint

A Trigger for Enforcing a Data Constraint

The View Ridge Gallery needs to track problem-customer accounts; these are customers who have either not paid promptly or who have presented other problems to the gallery. When a customer who is on the problem list attempts to make a purchase at the gallery, the gallery wants the transaction to be rolled back and a message displayed. Note that this feature requires an intertable CHECK constraint between the TRANS table and the CUSTOMER table, which, as we discussed in Chapter 7, requires a trigger to implement.

To enforce this policy and the corresponding constraint, we need to add a column to the CUSTOMER table named isProblemAccount. This column will use the SQL Server Bit data type, which can have the values NULL, 0, and 1. Zero indicates a good account, whereas a 1 indicates a problem account. And it looks like our new customer Melinda Gliddens had trouble with her previous payment, so we set her isProblemAccount value to 1:

-- Add column isProblemAccount to CUSTOMER /* *** SQL-ALTER-TABLE-CH10-01 *** */ ALTER TABLE dbo.CUSTOMER

ADD isProblemAccount Bit NULL DEFAULT '0'; -- Set initial column values for CUSTOMER.isProblemAccount /* *** SQL-UPDATE-CH10-01 *** */ UPDATE

dbo.CUSTOMER

SET

isProblemAccount = 0;

-- Set column value for Melinda Gliddens /* *** SQL-UPDATE-CH10-02 *** */ UPDATE

dbo.CUSTOMER

LastName = 'Gliddens'

AND

FirstName = 'Melinda';

-- Check CUSTOMER.isProblemAccount column values /* *** SQL-Query-CH10-02 *** */ SELECT

CustomerID, LastName, FirstName, isProblemAccount

FROM

dbo.CUSTOMER;

Chapter 10 Managing Databases with SQL Server 2008 R2

The results of the SELECT statement are:

Now we will create a trigger on TRANS named TRANS_CheckIsProblemAccount. With this trigger, when a customer makes a purchase the trigger determines whether the customer is flagged by the value of the isProblemAccount data in the CUSTOMER table. If so, the transaction is rolled back and a message is displayed. The trigger code in Figure 10-36 enforces this policy.

Note one interesting feature of the trigger code in Figure 10-36. As noted there, this trigger will fire for every update on TRANS, including updates fired by another trigger, such as TRANS_AfterInsertSetAskingPrice. But in that trigger, no customer is involved. Therefore, before completing the rest of this trigger, we have to be sure that there is actually a customer partici- pating in a transaction whose account status needs to be checked. This is done by the line:

IF (@CustomerID IS NULL) RETURN

Note that we only want to exit the TRANS_CheckIsProblemAccount trigger if there is no customer, not rollback the transaction that fired the trigger. When writing multiple triggers, remember that they may be run from other actions besides the one that you originally created them to handle.

OK, here comes Melissa to make another purchase—let’s see what happens.

/* *** SQL-UPDATE-CH10-03 *** */ UPDATE

TRANS SET

DateSold = '11/18/2010', SalesPrice = 475.00, CustomerID = 1056

WHERE TransactionID = 229;

The resulting output is shown in Figure 10-37. Looks like Melinda is off to talk to the manager about her account!

Using a table of valid or invalid values is more flexible and dynamic than placing such values in a CHECK constraint. For example, consider the

CHECK constraint on Nationality values in the ARTIST table. If the gallery manager wants to expand the nationality of allowed artists, the manager will have to change the CHECK constraint using the ALTER TABLE statement. In reality, the gallery manager will have to hire a consultant to change this constraint.

A better approach is to place the allowed values of Nationality in a table, say, ALLOWED_NATIONALITY. Then, write a trigger like that shown in Figure 10-36 to enforce the constraint that new values of Nationality exist in ALLOWED_NATIONALITY. When the gallery owner wants to change the allowed artists, the manager would simply add or remove values in the ALLOWED_NATIONALITY table.

Part 4 Multiuser Database Processing

Figure 10-36

The SQL Statements for the TRANS_CheckIsProblem Account Trigger