Вы находитесь на странице: 1из 70

O F F I C I A L

M I C R O S O F T

L E A R N I N G

P R O D U C T

6232B

Implementing a Microsoft SQL Server 2008 R2 Database

Volume 2

Designing and Implementing User-Defined Functions

13-1

Module 13
Designing and Implementing User-Defined Functions
Contents:
Lesson 1: Overview of Functions Lesson 2: Designing and Implementing Scalar Functions Lesson 3: Designing and Implementing Table-Valued Functions Lesson 4: Implementation Considerations for Functions Lesson 5: Alternatives to Functions Lab 13: Designing and Implementing User-Defined Functions 13-3 13-7 13-14 13-19 13-26 13-29

13-2

Implementing a Microsoft SQL Server 2008 R2 Database

Module Overview

Functions are routines that are used to encapsulate frequently performed logic. Rather than having to repeat all the function logic, any code that must perform the logic can call the function. In this lesson, you will learn the design and implementation of user-defined functions that enforce business rules or data consistency, or to modify and maintain existing functions written by other developers.

Objectives
After completing this lesson, you will be able to: Design and implement scalar functions Design and implement table-valued functions Describe implementation considerations for functions Describe alternatives to functions

Designing and Implementing User-Defined Functions

13-3

Lesson 1

Overview of Functions

Functions are routines made up of one or more Transact-SQL statements that can be used to encapsulate code for reuse. A function takes zero or more input parameters and returns either a scalar value or a table. Functions do not support output parameters, but do return results, either a single value or a table. This lesson provides an overview of functions and describes system functions.

Objectives
After completing this lesson, you will be able to: Describe different types of functions Use system functions

13-4

Implementing a Microsoft SQL Server 2008 R2 Database

Types of Functions

Key Points
Most high-level programming languages offer functions as blocks of code that are called by name and which can process input parameters. SQL Server has several types of functions: scalar functions, tablevalued functions, and system functions. Table-valued functions can be created in two ways. These are known as inline functions or multi-statement functions.

Scalar Functions
Scalar functions return a single data value of the type defined in a RETURNS clause. An example of a scalar function would be a function that extracts the protocol from a URL. From the string "http://www.microsoft.com", the function would return the string "http".

Inline table-valued functions


An inline table-valued function returns a table that is the result of a single SELECT statement. While this is similar to a view, an inline table-valued function is more flexible in that parameters can be passed to the SELECT statement. For example, if a table holds details of sales for an entire country, individual views could be created to return details of sales for particular states within the country. An inline table-valued function could be written, that takes the state code or ID as a parameter. In this way, only a single function would be needed to provide details for all states, rather than separate views for each state.

Multi-statement table-valued functions


A multi-statement table-valued function returns a table built by one or more Transact-SQL statements and is similar to a stored procedure. Multi-statement table-valued functions are created for the same reasons as inline table-valued functions, but are used when the logic that the function needs to implement is too complex to be expressed in a single SELECT statement.

Designing and Implementing User-Defined Functions

13-5

System Functions
System functions are built-in functions provided by SQL Server to help you perform a variety of operations. They cannot be modified. Question: How have you used functions in other programming languages?

13-6

Implementing a Microsoft SQL Server 2008 R2 Database

System Functions

Key Points
SQL Server has a wide variety of built-in function that you can use in queries to return data or to perform operations on data.

System Functions
Most of the functions are scalar functions and provide the functionality commonly provided by functions in other high-level languages such as operations on data types (including strings and dates and times) and conversions between data types. A library of mathematical and cryptographic functions is provided. Other functions provide details of the configuration of the system and its security. Aggregates such as MIN, MAX, AVG, SUM, and COUNT perform calculations across groups of rows. Many of these functions automatically ignore NULL rows. Ranking functions such as ROW_NUMBER, RANK, DENSE RANK, and NTILE perform windowing operations on rows of data. Question: What would a cryptographic function be used for?

Designing and Implementing User-Defined Functions

13-7

Lesson 2

Designing and Implementing Scalar Functions

You have seen that functions are routines made up of one or more Transact-SQL statements that can be used to encapsulate code for reuse, and that functions can take zero or more input parameters and return either scalar values or a tables. This lesson provides an overview of scalar functions and explains why and how you use them, in addition to the syntax for creating them.

Objectives
After completing this lesson, you will be able to: Explain a scalar function Create scalar functions Describe data type limitations Explain deterministic and non-deterministic functions

13-8

Implementing a Microsoft SQL Server 2008 R2 Database

What Is a Scalar Function?

Key Points
You use scalar functions to return information from a database. A scalar function returns a single data value of the type defined in a RETURNS clause.

Scalar Functions
Unlike the definition of a stored procedure, where the use of a BEGINEND that wraps the body of the stored procedure is optional, the body of the function must be defined in a BEGINEND block. The function body contains the series of Transact-SQL statements that return the value. For example, consider the following function definition:
CREATE FUNCTION dbo.ExtractProtocolFromURL ( @URL nvarchar(1000)) RETURNS nvarchar(1000) AS BEGIN RETURN CASE WHEN CHARINDEX(N':',@URL,1) >= 1 THEN SUBSTRING(@URL,1,CHARINDEX(N':',@URL,1) - 1) END; END; GO

Note that the body of the function comprises a single RETURN statement that is wrapped in a BEGINEND block. This function can be used as an expression wherever a single value could be used:
SELECT dbo.ExtractProtocolFromURL(N'http://www.microsoft.com'); GO IF (dbo.ExtractProtocolFromURL(@URL) = N'http') ...

Designing and Implementing User-Defined Functions

13-9

Scalar functions can also be implemented in managed code. Managed code will be discussed in Module 16. The allowable return values for scalar functions differ between functions that are defined in T-SQL and functions that are defined using managed code.

13-10

Implementing a Microsoft SQL Server 2008 R2 Database

Creating Scalar Functions

Key Points
User-defined functions are created using the CREATE FUNCTION statement, modified using the ALTER FUNCTION statement, and removed using the DROP FUNCTION statement. Even though the body of the function (apart from inline functions) must be wrapped in a BEGINEND block, the CREATE FUNCTION must be the only statement in the batch.

Scalar User-defined Functions


You use scalar functions to return information from a database. A scalar function returns a single data value of the type defined in a RETURNS clause. The body of the function, defined in a BEGINEND block, contains the series of Transact-SQL statements that return the value.

Guidelines
Consider the following guidelines when you create scalar user-defined functions: Make sure that you use two-part naming for the function and for all database objects referenced by the function. Avoid Transact-SQL errors that cause a statement to be canceled and continue with the next statement in the module (such as triggers or stored procedures) because they are treated differently inside a function. In functions, such errors cause the execution of the function to stop.

Side-effects
A function that modifies the underlying database is considered to have "side-effects". In SQL Server, functions are not permitted to have side-effects. You may not change data in a database within a function, may not call a stored procedure and may not execute dynamic SQL code.

Designing and Implementing User-Defined Functions

13-11

Deterministic and Non-deterministic Functions

Key Points
Both built-in and user-defined functions fall into one of two categories: deterministic and nondeterministic. This distinction is important as it determines where a function can be used.

Deterministic Functions
A deterministic function is one that will always return the same result when provided with the same set of input values and for the same database state. Consider the following function definition:
CREATE FUNCTION dbo.AddInteger (@FirstValue int, @SecondValue int) RETURNS int AS BEGIN RETURN @FirstValue + @SecondValue; END; GO

Every time the function is called with the same two integer values, it would return exactly the same result.

Non-deterministic Functions
A non-deterministic function is one that may return different results for the same set of input values each time it is called, even if the database remains in the same state. Consider the following function:
CREATE FUNCTION dbo.CurrentTimeInLondonAsString() RETURNS varchar(40) AS BEGIN RETURN CONVERT(varchar(40),SYSUTCDATETIME(),100); END;

13-12

Implementing a Microsoft SQL Server 2008 R2 Database

GO

Each time the function is called, it would return a different value, even though no input parameters are supplied. The OBJECTPROPERTY() function can be used to determine if a function is deterministic or not.

Designing and Implementing User-Defined Functions

13-13

Demonstration 2A: Scalar Functions

Key Points
In this demonstration you will see: How to create scalar user-defined functions How to query scalar user-defined functions How to determine if a scalar user-defined function is deterministic How to drop scalar user-defined functions

Demonstration Setup
1. 2. Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer. Open the 21 Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.

3. 4. 5.

13-14

Implementing a Microsoft SQL Server 2008 R2 Database

Lesson 3

Designing and Implementing Table-Valued Functions

In this lesson you will learn how to work with functions that return tables instead of single values. There are two types of table-valued functions (TVFs): inline and multi-statement. Both types of TVF will be covered in this lesson. The ability to return a table of data is important as it allows a function to be used as a source of rows in place of a table in a T-SQL statement. In many cases, this can avoid the need to store data temporarily in tables.

Objectives
After completing this lesson, you will be able to: Describe table-valued functions Describe Inline table-valued functions Describe multi-statement table-valued functions

Designing and Implementing User-Defined Functions

13-15

What are Table-valued Functions?

Key Points
Unlike scalar functions, TVFs return a table that can contain many rows of data, each with many columns.

Table-valued Functions
There are two ways to create TVFs. Inline TVFs return an output table defined by a RETURN statement that is comprised of a single SELECT statement. If the logic of the function is too complex to include in a single SELECT statement, the function needs to be implemented as a multi-statement TVF. Multi-statement TVFs construct a table within the body of the function and then return the table. They also need to define the schema of the table to be returned. Both types of TVF can be used as the equivalent of parameterized views.

13-16

Implementing a Microsoft SQL Server 2008 R2 Database

Inline Table-Valued Functions

Key Points
You can use inline functions to achieve the functionality of parameterized views. One of the limitations of a view is that you are not allowed to include a user-provided parameter within the view when you create it.

Inline TVFs
In the syntax example shown on the slide, note that the return type is TABLE. The definition of the columns of the table is not shown. You do not explicitly define the schema of the returned table. The output table schema is derived from the SELECT statement that you provide within the RETURN statement. For inline functions, the body of the function is not enclosed in a BEGINEND block. However, the CREATE FUNCTION statement must be the only statement in the batch. Question: TVFs return rows of data as tables. You have learned that tables do not have a predefined order. Why does the example function in the slide include an ORDER BY clause?

Designing and Implementing User-Defined Functions

13-17

Multi-statement Table-valued Functions

Key Points
A multi-statement table-valued function allows for more complexity in how the table to be returned is constructed. You can use user-defined functions that return a table to replace views. This is very useful when the logic required for constructing the return table is more complex than would be possible within the definition of a view.

Multi-statement TVFs
A table-valued function (like a stored procedure) can use complex logic and multiple Transact-SQL statements to build a table. In the example on the slide, a function is created that returns a table of dates. For each row, two columns are returned: the position of the date within the range of dates, and the calculated date. As the system does not already include a table of dates, a loop needs to be constructed to calculate the required range of dates. This cannot be implemented in a single SELECT statement unless another object such as a table of numbers, is already present in the database. In each iteration of the loop, an INSERT is performed into the table that is later returned. In the same way that you use a view, you can use a table-valued function in the FROM clause of a Transact-SQL statement. Question: Can you think of a situation where you would need to use a Multi-statement Table-valued Function rather than an Inline Table-valued Function?

13-18

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 3A: Implementing Table-Valued Functions

Key Points
In this demonstration you will see: How to create a table-valued function How to query a table-valued function How to drop a table-valued function

Demonstration Steps
1. If Demonstration 2A was not performed: Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 31 Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.

Question: What are some commonly used SQL Scalar functions that you can think of?

Designing and Implementing User-Defined Functions

13-19

Lesson 4

Implementation Considerations for Functions

While the ability to create functions in T-SQL is very important, there are some key considerations that need to be made when creating functions. In particular, it is important to avoid negative performance impacts through inappropriate use of functions. Performance problems due to such inappropriate usage are very common. This lesson provides guidelines for the implementation of functions and describes how to control their security context.

Objectives
After completing this lesson, you will be able to: Describe performance impacts of scalar functions Describe performance impacts of table-valued functions Control execution context Use EXECUTE AS clause Explain guidelines for creating functions

13-20

Implementing a Microsoft SQL Server 2008 R2 Database

Performance Impacts of Scalar Functions

Key Points
The code for views is incorporated directly into the code for the query that accesses the view. This is not the case for scalar functions.

Common Performance Problems


The over-use of scalar functions is a common cause of performance problems in SQL Server systems. In many cases, extracting the code from the function definition and incorporating it directly into the query will resolve the performance issue. You will see an example of this in the next lab.

Designing and Implementing User-Defined Functions

13-21

Performance Impacts of Multi-statement Table-valued Functions

Key Points
Whether or not the code for a TVF is incorporated into the query that uses the function depends upon the type of table-valued function. Inline TVFs are directly incorporated into the code of the query that uses them.

Common Performance Problems


Multi-statement TVFs are not incorporated into the code of the query that uses them. The inappropriate usage of such TVFs is a common cause of performance issues in SQL Server. The CROSS APPLY operator is used to call a table-valued function for each row in the left-hand table within the query. Designs that require the calling of a TVF for every row in a table can lead to significant performance overhead. You should examine the design to see if there is a way to avoid the need to call the function for each row.

13-22

Implementing a Microsoft SQL Server 2008 R2 Database

Controlling Execution Context

Key Points
Execution context is determined by the user or login connected to the session, or executing (calling) a module. Execution context establishes the identity against which permissions are checked. The user or login calling a module, such as a stored procedure or function, usually determines execution context. When you use the EXECUTE AS clause to change the execution context so that a code module executes as a user other than the caller, the code is said to impersonate the alternative user.

Designing and Implementing User-Defined Functions

13-23

The EXECUTE AS Clause

Key Points
The EXECUTE AS clause sets the execution context of a session. You can use the EXECUTE AS clause in a stored procedure or function to set the identity used as the execution context for the stored procedure or function. EXECUTE AS allows you to create procedures that execute code that the user executing the procedure is not permitted to execute, without the need for concerns regarding broken ownership chains or dynamic SQL execution.

13-24

Implementing a Microsoft SQL Server 2008 R2 Database

Guidelines for Creating Functions

Key Points
Consider the following guidelines when you create user-defined functions: The performance of inline functions is, in many cases, much higher than the performance of multistatement functions. Wherever possible, try to implement functions as inline functions. Avoid building large general purpose functions. Keep functions relatively small and targeted at a specific purpose. This will avoid code complexity but will also increase the opportunities for reusing the functions. Use two-part naming to qualify the name of any database objects referred to within the function and also use two-part naming when choosing the name of the function. Consider the impact of using functions in combination with indexes. In particular, note that a WHERE clause that uses a predicate like:
WHERE Function(CustomerID) = Value

is likely to remove the usefulness of an index on CustomerID.

Avoid statements that will raise T-SQL errors. Exception handling is not allowed within functions.

Designing and Implementing User-Defined Functions

13-25

Demonstration 4A: Execution Context

Key Points
In this demonstration you will see how to alter the execution context of a function.

Demonstration Steps
1. If Demonstration 2A was not performed: Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 41 Demonstration 4A.sql script file. Follow the instructions contained within the comments of the script file.

13-26

Implementing a Microsoft SQL Server 2008 R2 Database

Lesson 5

Alternatives to Functions

Functions are only one option for implementing code. This lesson explores situations where other solutions may or may not be appropriate and helps you make decisions about which solution to use.

Objectives
After completing this lesson, you will be able to: Compare table-valued functions and stored procedures Compare inline functions and views

Designing and Implementing User-Defined Functions

13-27

Comparing Table-valued Functions and Stored Procedures

Key Points
Table-valued functions and stored procedures can often be used to achieve similar outcomes. It is important to realize that not all client applications can call both and so they cannot necessarily be used interchangeably. There are also pros and cons of each approach. While it is possible to access the output rows of a stored procedure with an INSERT EXEC statement, it is easier to consume the output of a function in code than the output of a stored procedure. For example, you cannot execute the following code:
SELECT * FROM (EXEC dbo.GetCriticalPathNodes);

The output of a function could be assigned to a variable in code. Stored procedures can modify data in database tables. Functions cannot modify data in database tables. Functions that include such "side-effects" are not permitted. Functions can have significant performance impacts when not inlined and called for each row in a query. Stored procedures can execute dynamic SQL statements. Functions are not permitted to execute dynamic SQL statements. Stored procedures can include detailed exception handling. Functions cannot contain exception handling. Stored procedures can return multiple resultsets from a single stored procedure call. Table-valued functions are able to return a single rowset from a function call. There is no mechanism to permit the return of multiple rowsets from a single function call.

13-28

Implementing a Microsoft SQL Server 2008 R2 Database

Comparing Table-valued Functions and Views

Key Points
TVFs can provide similar outcomes to views. Views and parameter-less TVFs are usually able to be consumed by most client application that can access tables. Not all such applications can pass parameters to a table-valued function. Views and inline TVFs can be updatable. Multi-statement TVFs are not updatable. Inline TVFs are updatable. Views can have INSTEAD OF triggers associated with them. This is mostly used to provide for updatable views based on multiple base tables. Views and inline table-valued functions are incorporated into surrounding queries. Scalar and multistatement table-valued functions are not incorporated into surrounding queries and often lead to performance issues when used inappropriately.

Designing and Implementing User-Defined Functions

13-29

Lab 13: Designing and Implementing User-Defined Functions

Lab Setup
For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 1. 2. 3. On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window. In the Virtual Machines list, if the virtual machine 623XB-MIA-DC is not started: 4. Right-click 623XB-MIA-DC and click Start. Right-click 623XB-MIA-DC and click Connect. In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears, and then close the Virtual Machine Connection window.

In the Virtual Machines list, if the virtual machine 623XB-MIA-SQL is not started: Right-click 623XB-MIA-SQL and click Start. Right-click 623XB-MIA-SQL and click Connect. In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears.

5. 6. 7.

In Virtual Machine Connection window, click on the Revert toolbar icon. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. In the Virtual Machine Connection window, if the user is not already logged on: On the Action menu, click the Ctrl-Alt-Delete menu item. Click Switch User, and then click Other User.

13-30

Implementing a Microsoft SQL Server 2008 R2 Database

Log on using the following credentials:

i. User name: AdventureWorks\Administrator ii. Password: Pa$$w0rd 8. From the View menu, in the Virtual Machine Connection window, click Full Screen Mode. 9. If the Server Manager window appears, check the Do not show me this console at logon check box and close the Server Manager window. 10. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio. 11. In Connect to Server window, type Proseware in the Server name text box. 12. In the Authentication drop-down list box, select Windows Authentication and click Connect. 13. In the File menu, click Open, and click Project/Solution. 14. In the Open Project window, open the project D:\6232B_Labs\6232B_13_PRJ\6232B_13_PRJ.ssmssln. 15. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Lab Scenario
The existing marketing application includes some functions. Your manager has requested your assistance in creating a new function for formatting phone numbers. She also needs you to modify an existing function to improve its usability. Finally, if you have time, she would also like you to explore a performance-related problem with another existing function.

Supporting Documentation
Function Specifications: Phone Number Function Name: FormatPhoneNumber (created in the dbo schema) Input Parameter: PhoneNumberToFormat nvarchar(16) Return Value: nvarchar(16) Rules to apply in formatting: Any phone number beginning with the international dialing code (ie: a + sign), should be left unformatted. Phone numbers that contain 10 digits should be formatted as: (XXX) XXX-XXXX Phone numbers that contain 8 digits should be formatted as: XXXX-XXXX Phone numbers that contain 7 digits should be formatted as: XXX-XXXX Phone numbers that contain 6 digits should be formatted as: XXX-XXX All other characters should be stripped out Phone numbers that have different numbers of digits should have only the digits returned ie: (9234) 2345-2342 should be returned as 923423452342.

Requirements: Comma-Delimited List Function You need to create another version of this function called dbo.IntegerListToTable that takes a commadelimited list of integers and returns a similar table. You need to design, implement and test the function. You can assume that all integers sent to the function will be eight digits or less in length. Problematic Query
SELECT dbo.JoinNames(FirstName,MiddleName,LastName) AS FullName

Designing and Implementing User-Defined Functions

13-31

FROM Marketing.Prospect ORDER BY FullName;

13-32

Implementing a Microsoft SQL Server 2008 R2 Database

Exercise 1: Formatting Phone Numbers


Scenario
ScenarioYour manager has noticed that phone numbers that are entered into the database tend to be formatted in different ways by different users. She has asked you to create a function that will be used to format the phone numbers. You need to design, implement and test the function. The main tasks for this exercise are as follows: 1. 2. 3. Review the requirements. Design and create the function. Test the function.

Task 1: Review the design requirements


Review the Function Specifications: Phone Number in the supporting documentation.

Task 2: Design and create the function


Design and create the function for reformatting phone numbers.

Task 3: Test the function


Execute the FormatPhoneNumber function to ensure function correctly formats the phone number. Results: After this exercise, you should have created a new FormatPhoneNumber function within the dbo schema.

Designing and Implementing User-Defined Functions

13-33

Exercise 2: Modifying an Existing Function


Scenario
An existing function dbo.StringListToTable takes a comma-delimited list of strings and returns a table. In some application code, this causes issues with data types as the list often contains integers rather than just simple strings. The main tasks for this exercise are as follows: 1. 2. 3. 4. Review the requirements. Design and create the function. Test the function. Test the function with an alternate delimiter such as the pipe | character.

Task 1: Review the requirements


Review the requirement for the dbo.IntegerListToTable function in the Supporting Documentation.

Task 2: Design and create the function


Design and create the dbo.IntegerListToTable function.

Task 3: Test the function


Execute the dbo.IntegerListToTable function to ensure it returns the correct results.

Task 4: Test the function with an alternate delimiter such as the pipe | character
Test the dbo.IntegerListToTable function and pass in an alternate delimiter such as the pipe | character. Results: After this exercise, you should have created a new IntegerListToTable function within a dbo schema.

13-34

Implementing a Microsoft SQL Server 2008 R2 Database

Challenge Exercise 3: Resolve a Function-related Performance Issue (Only if time permits)


Scenario
The operations team manager has approached you about a query that is performing badly. You need to investigate it and suggest changes that might improve its performance. The main tasks for this exercise are as follows: 1. 2. 3. Review the query Design an alternate query Use SET STATISTICS TIME ON to compare the performance of the new and old queries

Task 1: Review the query


Review the problematic query in the Supporting Documentation.

Task 2: Design an alternate query


Design the query.

Task 3: Use SET STATISTICS TIME ON to compare the performance of the new and old
queries
Turn SET STATISTICS TIME ON. Use the times returned to test how your new query compares with the original. Results: After this exercise, you should have created an alternate query for the poorly-performing query.

Designing and Implementing User-Defined Functions

13-35

Module Review and Takeaways

Review Questions
1. 2. When using the EXECUTE AS clause, what privileges should the login or user being impersonated have? When using the EXECUTE AS clause, what privileges should the login or user creating the code have?

Best Practices
1. 2. Avoid calling multi-statement TVFs for each row of a query. In many cases, you can dramatically improve performance by extracting the code from the query into the surrounding query. Use the WITH EXECUTE AS clause to override the security context of code that needs to perform actions that the user that is executing the code, does not have.

Responding to Data Manipulation via Triggers

15-1

Module 15
Responding to Data Manipulation via Triggers
Contents:
Lesson 1: Designing DML Triggers Lesson 2: Implementing DML Triggers Lesson 3: Advanced Trigger Concepts Lab 15: Responding to Data Manipulation via Triggers 15-3 15-13 15-20 15-30

15-2

Implementing a Microsoft SQL Server 2008 R2 Database

Module Overview

Data manipulation language (DML) triggers are a powerful tool that enables you to enforce domain, entity, and referential data integrity and business logic. The enforcement of integrity helps you to build reliable applications. In this lesson, you will learn what DML triggers are and how they enforce data integrity, the different types of triggers available to you, and how to define triggers in your database.

Objectives
After completing this module, you will be able to: Design DML triggers Implement DML triggers Explain advanced DML trigger concepts

Responding to Data Manipulation via Triggers

15-3

Lesson 1

Designing DML Triggers

Before beginning to create DML triggers, it is important to become familiar with how they should be designed, to avoid making common design errors. Several types of DML triggers are available. It is important to know what they do and how they work and it is also important to understand how they differ from DDL triggers. DML triggers need to be able to work with both the previous state of the database and its changed state. You will see how the inserted and deleted virtual tables provide that capability. As DML triggers are often added after applications are built, it is important then to make sure that adding a trigger does not cause errors in the applications that were designed without them being in place. SET NOCOUNT ON helps avoid side effects of triggers.

Objectives
After completing this lesson, you will be able to: Describe DML triggers. Explain how AFTER triggers differ from INSTEAD OF triggers and where each should be used. Access both the prior and final states of the database data by using the inserted and deleted virtual tables. Avoid impacting existing applications by using SET NOCOUNT ON. Describe performance-related considerations for triggers.

15-4

Implementing a Microsoft SQL Server 2008 R2 Database

What are DML Triggers?

Key Points
A DML trigger is a special kind of stored procedure that executes when an INSERT, UPDATE, or DELETE statement modifies the data in a specified table or view. This includes any INSERT, UPDATE, or DELETE statement that form part of a MERGE statement. A trigger can query other tables and can include complex Transact-SQL statements. DDL triggers are similar to DML triggers but DDL triggers fire when DDL events occur. DDL events occur for most CREATE, ALTER or DROP statements in the T-SQL language. Logon triggers are a special form of trigger that fire when a new session is established. There is no concept of a Logoff trigger at present.

Trigger Operation
The trigger and the statement that fires it are treated as a single operation, which can be rolled back from within the trigger. The ability to roll back a transaction allows you to undo the effect of a T-SQL statement if the logic in your triggers decides that the statement should not have been executed. If the statement is part of another transaction, that outer transaction is also rolled back. Triggers can cascade changes through related tables in the database; however, in many cases, these changes can be executed more efficiently by using cascading referential integrity constraints.

Complex Logic and Meaningful Error Messages


Triggers can guard against malicious or incorrect INSERT, UPDATE, and DELETE operations and enforce other restrictions that are more complex than those defined by using CHECK constraints. For example, a trigger could check referential integrity for one column, only when another column holds a specific value. Unlike CHECK constraints, triggers can reference columns in other tables. For example, a trigger can use a SELECT statement from another table to compare to the inserted or updated data and to perform additional actions, such as modifying the data or displaying a user-defined error message.

Responding to Data Manipulation via Triggers

15-5

Triggers can evaluate the state of a table before and after a data modification and take actions based on that difference. For example, you may wish to check that the balance of a customer's account does not change by more than a certain amount, if the person processing the change is not a manager. Triggers also allow the use of custom error messages for when constraint violations occur. This could make the messages that are passed to end users more meaningful.

Multiple Triggers
Multiple triggers of the same type (INSERT, UPDATE, or DELETE) on a table allow multiple different actions to take place in response to the same modification statement. Question: Why would you choose to use a DML trigger instead of a constraint?

15-6

Implementing a Microsoft SQL Server 2008 R2 Database

AFTER Triggers vs. INSTEAD OF Triggers

Key Points
There are two types of DML triggers: AFTER triggers and INSTEAD OF triggers. The main difference between them relates to when they fire. One fires after the event, the other fires instead of the event. Each type of DML trigger can be implemented in either T-SQL or in managed code. In this module, you will explore how they are designed and implemented using T-SQL. Managed code is described in Module 16: Implementing Managed Code in SQL Server. It is important to realize that even if an UPDATE (or other data modification statement) modifies many rows, the trigger only fires a single time. For that reason, triggers need to be designed to handle multiple rows. This design is different to other database engines where triggers are written to target single rows and are called multiple times when a statement affects multiple rows.

AFTER Triggers
AFTER triggers fire after the data modifications that are part of the event that they relate to completes. This means that an INSERT, UPDATE, or DELETE statement executes and modifies the data in the database. After that modification has completed, AFTER triggers associated with that event then fire. Common reasons for implementing AFTER triggers are: Providing auditing of the changes that were made. Implementing complex rules involving the relationship between tables. Implementing default values or calculated values within rows.

In many cases, trigger-based code can be replaced by other forms of code. For example, auditing might be provided by SQL Server Audit (discussed in course 6231B Maintaining a SQL Server 2008 R2 Database). Relationships between tables are more typically implemented via foreign key constraints. Default values and calculated values are typically implemented via DEFAULT constraints and persisted

Responding to Data Manipulation via Triggers

15-7

calculated columns. In some situations though, the complexity of the logic required will make triggers a good solution. If the trigger executes a ROLLBACK statement, the data modification statement that it is associated with will be rolled back. If that statement was part of a larger transaction, that other transaction would be rolled back too.

INSTEAD OF Triggers
INSTEAD OF triggers are a special type of trigger that executes alternate code instead of executing the statement that they were fired from. It is important to realize that with an INSTEAD OF trigger, only the code in the trigger is executed. A very common use case for INSTEAD OF triggers is to allow views that are based on multiple base tables to be updatable. Question: Why would the ability to run alternate code help to allow views with multiple base tables to be updatable?

15-8

Implementing a Microsoft SQL Server 2008 R2 Database

Inserted and Deleted Virtual Tables

Key Points
When designing a trigger, it is important to be able to make decisions based on what changes have been made to the data. To arrive at effective decisions, access is needed to details of both the unmodified and modified versions of the data. DML triggers provide this via a pair of virtual tables called inserted and deleted. These virtual tables are often then joined to the modified table data as part of the logic within the trigger.

inserted Virtual Table


After an INSERT operation, the inserted virtual table holds details of the rows just inserted. The underlying table also has those rows in it. After an UPDATE operation, the inserted virtual table holds details of the modified versions of the rows. The underlying table also has those rows in the modified form.

deleted Virtual Table


After a DELETE operation, the deleted virtual table holds details of the rows just deleted. The underlying table no longer contains those rows. After an UPDATE operation, the deleted virtual table holds details of the rows prior to the modification being made. The underlying table holds the modified versions.

INSTEAD OF Triggers and the inserted and deleted Virtual Tables


When an INSERT, DELETE, or UPDATE statement is attempted and an INSTEAD OF trigger is associated with the event on the table, the inserted and deleted virtual tables hold details of the modifications that need to be made but have not yet been made.

Responding to Data Manipulation via Triggers

15-9

Scope of inserted and deleted


The inserted and deleted virtual tables are only available during the execution of the trigger code and are scoped directly to the trigger code. This means that if the trigger code was to execute a stored procedure, that stored procedure would not have access to the inserted and deleted virtual tables.

15-10

Implementing a Microsoft SQL Server 2008 R2 Database

SET NOCOUNT ON

Key Points
When adding a trigger to a table, it is important to avoid breaking any existing applications that are accessing the table unless the intended purpose of the trigger is to avoid misbehaving applications from making inappropriate data changes. It is common for application programs to issue data modification statements and to check the returned count of the number of rows affected. This is often done as part of an optimistic concurrency check. For example, consider the following code:
UPDATE Customer SET Customer.FullName = @NewName, Customer.Address = @NewAddress WHERE Customer.CustomerID = @CustomerID AND Customer.Concurrency = @Concurrency;

In this case, the column Concurrency is a rowversion data type column. The application was designed so that the update only occurs if the Concurrency column has not been altered. With rowversion columns, every modification to the row causes a change in the rowversion column. When the application intends to modify a single row, it issues an UPDATE statement for that row. The application then checks the count of updated rows that is returned by SQL Server. When the application sees that only a single row has been modified, the application knows that only the row it intended to change was changed. It also knows that no other user had modified the row since the application read the data. A common mistake when adding triggers is that if the trigger also causes row modifications (for example, writes an audit row into an audit table), that count is returned in addition to the expected count. This situation can be avoided by the SET NOCOUNT ON statement. Most triggers should include this statement.

Responding to Data Manipulation via Triggers

15-11

Returning Rowsets
While it is possible to include a SELECT statement within a trigger and for it to return rows, the creation of this type of side-effect is discouraged. In future versions of SQL Server, the ability to do this is likely to be removed. In SQL Server 2008 R2, there is a configuration setting disallow results from triggers which when set to 1, will disallow this capability.

15-12

Implementing a Microsoft SQL Server 2008 R2 Database

Trigger Performance Considerations

Key Points
In general, constraints are preferred to triggers for performance reasons. Triggers are also complex to debug as the actions they perform are not visible directly in the code that causes them to fire. Triggers also increase the time taken for data modification transactions as they add extra steps that SQL Server needs to process during these operations.

Constraints vs. Triggers


When an AFTER trigger decides to disallow a data modification, it does so by executing a ROLLBACK statement. This causes the entire work done by the statement to then be undone by the ROLLBACK. Higher performance is obtained by avoiding the data modification ever occurring. Constraints are checked before any data modification is attempted and so often provide much higher performance than is possible with triggers, particularly in ROLLBACK situations. Constraints are used when the checks that need to be performed are relatively simple. Triggers allow complex logic to be checked.

RowVersions and tempdb


Since SQL Server 2005, trigger performance has been improved when compared to earlier versions. In earlier versions, the inserted and deleted virtual tables were essentially like a view above the data in the transaction log. The data in these tables needed to be reconstructed when it was required. From SQL Server 2005 onwards, a special rowversion table was provided in the tempdb database. This special table holds copies of the data in the inserted and deleted virtual tables for the duration of the trigger. This design improved the performance of triggers but means that excessive usage of triggers could cause performance issues within the tempdb database.

Responding to Data Manipulation via Triggers

15-13

Lesson 2

Implementing DML Triggers

Lesson 1 provided information on designing DML triggers. It is now important to consider how to implement the designs that have been created.

Objectives
After completing this lesson, you will be able to: Implement AFTER INSERT triggers. Implement AFTER DELETE triggers. Implement AFTER UPDATE triggers.

15-14

Implementing a Microsoft SQL Server 2008 R2 Database

AFTER INSERT Triggers

Key Points
An INSERT trigger is a trigger that executes whenever an INSERT statement enters data into a table or a view on which the trigger is configured. The action of the INSERT statement is completed before the trigger fires.

AFTER INSERT Trigger Actions


When an AFTER INSERT trigger fires, new rows are added to both the base table and to the inserted virtual table. The inserted virtual table holds a copy of the rows that have been inserted into the base table. The trigger can examine the inserted virtual table to determine whether or how the trigger actions should be executed.

Multi-Row Inserts
In the example shown, insertions to the table Sales.Opportunity are being audited to a table called Sales.OpportunityAudit. Note that the trigger processes all inserted rows at once. A common error when designing AFTER INSERT triggers is to write them with the assumption that only a single row is being inserted. Question: When would you use an INSERT trigger?

Responding to Data Manipulation via Triggers

15-15

Demonstration 2A: AFTER INSERT Triggers

Key Points
In this demonstration you will see how to: Create an AFTER INSERT trigger Test the trigger action Drop the trigger

Demonstration Steps
1. 2. Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer. Open the 21 Demonstration 2A.sql script file. Follow the instructions contained within the comments of the script file.

3. 4. 5.

15-16

Implementing a Microsoft SQL Server 2008 R2 Database

AFTER DELETE Triggers

Key Points
A DELETE trigger is a trigger that executes whenever a DELETE statement deletes data from a table or view on which the trigger is configured. The action of the DELETE statement is completed before the trigger fires.

AFTER DELETE Trigger Actions


When an AFTER DELETE trigger fires, rows are removed from the base table and added to the deleted virtual table. The deleted virtual table holds a copy of the rows that have been deleted from the base table. The trigger can examine the deleted virtual table to determine whether or how the trigger actions should be executed.

Multi-Row Deletes
In the example shown, rows in the Product.Product table are being flagged as discontinued if the product category row they are associated with in the Product.Category table is deleted. Note that the trigger processes all deleted rows at once. A common error when designing AFTER DELETE triggers is to write them with the assumption that only a single row is being deleted.

TRUNCATE TABLE
When rows are deleted from a table using a DELETE statement, any AFTER DELETE triggers are fired when the deletion is completed. TRUNCATE TABLE is an administrative option that removes all rows from a table. It needs additional permissions above those required for deleting rows. It does not fire any AFTER DELETE triggers associated with the table. Question: What performance and archival considerations should you think about when planning how to handle deleted records?

Responding to Data Manipulation via Triggers

15-17

Demonstration 2B: AFTER DELETE Triggers

Key Points
In this demonstration you will see how to: Create an AFTER DELETE trigger Test the trigger Drop the trigger

Demonstration Steps
1. If Demonstration 2A was not performed: Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 22 Demonstration 2B.sql script file. Follow the instructions contained within the comments of the script file.

15-18

Implementing a Microsoft SQL Server 2008 R2 Database

AFTER UPDATE Triggers

Key Points
An UPDATE trigger is a trigger that executes whenever an UPDATE statement modified data in a table or a view on which the trigger is configured. The action of the UPDATE statement is completed before the trigger fires.

AFTER UPDATE Trigger Actions


When an AFTER UPDATE trigger fires, update actions are treated as a set of deletions of how the rows were and insertions of how the rows now are. Rows that are to be modified in the base table are copied to the deleted virtual table and the updated versions of the rows are copied to the inserted virtual table. The inserted virtual table holds a copy of the rows in their modified state, the same as how the rows appear now in the base table. The trigger can examine both the inserted and deleted virtual tables to determine whether and how the trigger actions should be executed.

Multi-Row Updates
In the example shown, the table Product.ProductReview contains a column called ModifiedDate. The trigger is being used to ensure that as changes are made to the Product.ProductReview table that the value in this column always reflects when any changes last happened. Note that the trigger processes all updated rows at once. A common error when designing AFTER UPDATE triggers is to write them with the assumption that only a single row is being updated. Question: When would you imagine you might use an UPDATE trigger in your own coding?

Responding to Data Manipulation via Triggers

15-19

Demonstration 2C: AFTER UPDATE Triggers

Key Points
In this demonstration you will see how to: Create an AFTER UPDATE trigger Test the trigger Query the sys.triggers view

Demonstration Steps
1. If Demonstration 2A was not performed: Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 23 Demonstration 2C.sql script file. Follow the instructions contained within the comments of the script file.

15-20

Implementing a Microsoft SQL Server 2008 R2 Database

Lesson 3

Advanced Trigger Concepts

In Lessons 1 and 2, you have learned to design and implement DML AFTER triggers. There are additional areas of complexity related to triggers that also need to be understood to make effective use of them. It is also important to understand where to use triggers and where to consider alternatives to triggers. Provide a brief introduction to this lesson in normal text. A module must have at least two lessons.

Objectives
After completing this lesson, you will be able to: Implement INSTEAD OF DML triggers. Explain how nested triggers work and how configurations might affect their operation. Explain additional considerations for recursive triggers that is triggers that include actions that cause the same trigger to fire again. Use the UPDATE function to build logic based on the columns being updated. Describe the limited control that can be exerted over the order that triggers fire in when multiple triggers are defined for the same event on the same object. Explain the alternatives to using triggers.

Responding to Data Manipulation via Triggers

15-21

INSTEAD OF Triggers

Key Points
INSTEAD OF triggers cause the execution of alternate code instead of executing the statement that they were fired from.

INSTEAD OF vs BEFORE Triggers


Some other database engines provide BEFORE triggers. In those databases, the action in the BEFORE trigger happens before the data modification statement which also occurs. SQL Server INSTEAD OF triggers are different from the BEFORE triggers that you may have come across in other database engines. It is important to realize that with an INSTEAD OF trigger as implemented in SQL Server, only the code in the trigger is executed. The original operation that caused the trigger to fire is not executed.

Updatable Views
A very common use case for INSTEAD OF triggers is to allow views that are based on multiple base tables to be updatable. INSTEAD OF triggers can be defined on views with one or more base tables, where they can extend the types of updates a view can support. This trigger executes instead of the original triggering action. INSTEAD OF triggers increase the variety of types of updates that you can perform against a view. Each table or view is limited to one INSTEAD OF trigger for each triggering action (INSERT, UPDATE, or DELETE). You can specify an INSTEAD OF trigger on both tables and views. You cannot create an INSTEAD OF trigger on views that have the WITH CHECK OPTION defined. Question: What sort of situations would lead you to need to execute different statements to the data modification statements requested?

15-22

Implementing a Microsoft SQL Server 2008 R2 Database

Demonstration 3A: INSTEAD OF Triggers

Key Points
In this demonstration you will see how to: Create an INSTEAD OF trigger Test the trigger

Demonstration Steps
1. If Demonstration 2A was not performed: Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 31 Demonstration 3A.sql script file. Follow the instructions contained within the comments of the script file.

Question: Why does the DELETE succeed when INSERT and UPDATE fail?

Responding to Data Manipulation via Triggers

15-23

How Nested Triggers Work

Key Points
Triggers can contain UPDATE, INSERT, or DELETE statements. When these statements on one table cause triggers on another table to fire, the triggers are considered to be nested.

Nested Triggers
Triggers are often used for auditing purposes. Nested triggers are essential for full auditing to occur. Otherwise, actions would occur on tables without being audited. It is possible to control whether or not nested trigger actions are permitted. By default, these actions are permitted via a configuration option at the server level. A failure at any level of a set of nested triggers cancels the entire original statement, and all data modifications are rolled back. A nested trigger will not fire twice in the same trigger transaction; a trigger does not call itself in response to a second update to the same table within the trigger.

Complexity of Debugging
It was mentioned in an earlier lesson that debugging triggers can be difficult. Nested and recursive triggers are particularly difficult to debug. One common method that is used during debugging is to include PRINT statements within the trigger code bodies so that you can determine where a failure occurred. Question: How might nested triggers work in an Employee database?

15-24

Implementing a Microsoft SQL Server 2008 R2 Database

Considerations for Recursive Triggers

Key Points
A recursive trigger is a trigger that performs an action that causes the same trigger to fire again either directly or indirectly. Any trigger can contain an UPDATE, INSERT, or DELETE statement that affects the same table or another table. With the recursive trigger option enabled, a trigger that changes data in a table can activate itself again, in a recursive execution.

Direct Recursion
Direct recursion occurs when a trigger fires and performs an action on the same table that causes the same trigger to fire again. For example, an application updates table T1, which causes trigger Trig1 to fire. Trig1 updates table T1 again, which causes trigger Trig1 to fire again.

Indirect Recursion
Indirect recursion occurs when a trigger fires and performs an action that causes another trigger to fire (in the same or a different table), and subsequently causes an update to occur on the original table. This, then, causes the original trigger to fire again. For example, an application updates table T2, which causes trigger Trig2 to fire. Trig2 updates table T3, which causes trigger Trig3 to fire. Trig3 in turn updates table T2, which causes Trig2 to fire again. If a trigger modifies a table that causes another trigger to fire, and the second trigger modifies the original table, the original trigger will fire recursively. To prevent indirect recursion of this sort, turn off the nested triggers option. You can use the RECURSIVE_TRIGGERS database option to enable or disable direct recursion in triggers. Question: Think of a database containing genealogy data. How might a recursive trigger be used when a relationship between two people is corrected (such as from child and parent to grandchild and grandparent, with an intermediate generation inserted)?

Responding to Data Manipulation via Triggers

15-25

UPDATE Function

Key Points
It is a common requirement to build logic that only takes action if particular columns are being updated.

UPDATE Function
The UPDATE function should not be confused with the UPDATE statement. The UPDATE function allows detection of whether or not a particular column is being updated in the action of an UPDATE statement. For example, you might wish to take a particular action only when the Size of a product changes. The column is referenced by the name of the column.

Change of Value
Note that this function does not indicate if the value is actually changing. It only indicates if the column is part of the list of columns in the SET clause of the UPDATE statement. To detect if the value in a column is actually being changed to a different value, the inserted and deleted virtual tables need to be interrogated.

COLUMNS_UPDATED Function
SQL Server also provides a function called COLUMNS_UPDATED. This function returns a bitmap that indicates which columns are being updated. The values in the bitmap depend upon the positional information for the columns. Hard-coding that sort of information in the code within a trigger is generally not considered good coding practice as it affects the readability (and hence the maintainability) of your code.

15-26

Implementing a Microsoft SQL Server 2008 R2 Database

Trigger Firing Order

Key Points
It is possible to assign multiple triggers to a single event on a single object. Only limited control is available over the firing order of these triggers.

sp_settriggerorder
Developers often seek to control the firing order of multiple triggers defined for a single event on a single object. For example, a developer might create three AFTER INSERT triggers on the same table, each implementing different business rules or administrative tasks. In general, code within one trigger should not depend upon the order of execution of other triggers. Limited control of firing order is available through the sp_settriggerorder system stored procedure. It allows you to specify which trigger fires first and which trigger fires last, from a set of triggers that all apply to the same event on the same object. The value for the @order parameter is either First, Last, or None. None is the default action. An error will occur if the First and Last triggers both refer to the same trigger. The value for the @stmttype parameter is INSERT, UPDATE, or DELETE for DML triggers.

Responding to Data Manipulation via Triggers

15-27

Alternatives to Using Triggers

Key Points
Triggers allow for complex logic and are sometimes necessary. Triggers are often though, used in situations where other alternatives would be preferable.

Checking Values
Triggers could be used to check that values in columns are valid or within given ranges. In general, CHECK constraints should be used for this instead of triggers as they are checked before the data modification is attempted. If the trigger is being used to check the correlation of values across multiple columns within the table, in general table-level CHECK constraints should be created instead.

Defaults
Triggers can be used to provide default values for columns when no values have been provided in INSERT statements. DEFAULT constraints should generally be used for this instead.

Foreign Keys
Triggers can be used to check the relationship between tables. In general, FOREIGN KEY constraints should be used for this.

Computed Columns
Triggers can be used to maintain the value in one column based on the value in other columns. In general, computed columns or persisted computed columns should be used for this.

Pre-calculating Aggregates
Triggers can be used to maintain pre-calculated aggregates in one table, based on the values in rows in another table. In general, indexed views should be used to provide this functionality.

15-28

Implementing a Microsoft SQL Server 2008 R2 Database

Constraint Use Is Not Always Possible


While general guidelines are provided here, replacing the triggers with these alternatives is not always possible. For example, the logic required when checking values might be too complex for a CHECK constraint. As another example, a FOREIGN KEY cannot be contained on a column that is also used for other purposes. Consider a column that holds an employee number only if another column holds the value E. While this typically indicates a poor database design, triggers can be used to ensure this sort of relationship.

Responding to Data Manipulation via Triggers

15-29

Demonstration 3B: Replacing Triggers with Computed Columns

Key Points
In this demonstration you will see how a trigger could be replaced by a computed column.

Demonstration Steps
1. If Demonstration 2A was not performed: Revert the 623XB-MIA-SQL virtual machine using Hyper-V Manager on the host system. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, click SQL Server Management Studio. In the Connect to Server window, type Proseware in the Server name text box and click Connect. From the File menu, click Open, click Project/Solution, navigate to D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln and click Open. Open and execute the 00 Setup.sql script file from within Solution Explorer.

2. 3.

Open the 32 Demonstration 3B.sql script file. Follow the instructions contained within the comments of the script file.

15-30

Implementing a Microsoft SQL Server 2008 R2 Database

Lab 15: Responding to Data Manipulation via Triggers

Lab Setup
For this lab, you will use the available virtual machine environment. Before you begin the lab, you must complete the following steps: 1. 2. 3. On the host computer, click Start, point to Administrative Tools, and then click Hyper-V Manager. Maximize the Hyper-V Manager window. In the Virtual Machines list, if the virtual machine 623XB-MIA-DC is not started: 4. Right-click 623XB-MIA-DC and click Start. Right-click 623XB-MIA-DC and click Connect. In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears, and then close the Virtual Machine Connection window.

In the Virtual Machines list, if the virtual machine 623XB-MIA-SQL is not started: Right-click 623XB-MIA-SQL and click Start. Right-click 623XB-MIA-SQL and click Connect. In the Virtual Machine Connection window, wait until the Press CTRL+ALT+DELETE to log on message appears.

5. 6. 7.

In Virtual Machine Connection window, click on the Revert toolbar icon. If you are prompted to confirm that you want to revert, click Revert. Wait for the revert action to complete. In the Virtual Machine Connection window, if the user is not already logged on: On the Action menu, click the Ctrl-Alt-Delete menu item. Click Switch User, and then click Other User.

Responding to Data Manipulation via Triggers

15-31

Log on using the following credentials: I. II. User name: AdventureWorks\Administrator Password: Pa$$w0rd

8. 9. 10. 11. 12. 13. 14. 15.

From the View menu, in the Virtual Machine Connection window, click Full Screen Mode. If the Server Manager window appears, check the Do not show me this console at logon check box and close the Server Manager window. In the virtual machine, click Start, click All Programs, click Microsoft SQL Server 2008 R2, and click SQL Server Management Studio. In Connect to Server window, type Proseware in the Server name text box. In the Authentication drop-down list box, select Windows Authentication and click Connect. In the File menu, click Open, and click Project/Solution. In the Open Project window, open the project D:\6232B_Labs\6232B_15_PRJ\6232B_15_PRJ.ssmssln. In Solution Explorer, double-click the query 00-Setup.sql. When the query window opens, click Execute on the toolbar.

Lab Scenario
You are required to audit any changes to data in a table that hold sensitive balance data. You have decided to implement this via DML triggers as the requirements in this case are not provided for directly by the SQL Server Audit mechanism.`

Supporting Documentation
The Marketing.CampaignAudit table is used to hold audit entries. When inserting rows into this table, the data required in each column is as shown in the following table: Column CampaignAuditID AuditTime ModifyingUser RemainingBalance Data Type int datetime2 sysname decimal(18,2) Value to Insert IDENTITY SYSDATETIME() ORIGINAL_LOGIN() RemainingBalance after update

15-32

Implementing a Microsoft SQL Server 2008 R2 Database

Exercise 1: Creating and Testing the Audit Trigger


Scenario
The Marketing.CampaignBalance table includes a column called RemainingBalance. Any time an update is made to the table, if either the existing balance or the new balance is greater than 10000, an entry needs to be written to the audit table Marketing.CampaignAudit. Note: Inserts or Deletes to the table do not need to be audited. Details of the current user can be taken from the function ORIGINAL_LOGIN(). The main tasks for this exercise are as follows: 1. 2. 3. Review the supporting documentation and existing system. Design a trigger to meet the requirements as stated in the scenario for this exercise. Write code to test the behavior of the trigger.

Task 1: Review the supporting documentation and existing system


Review the existing structure of the Marketing.CampaignAudit table and the values required in each column, based on the supporting documentation. Review the existing structure of the Marketing.CampaignBalance table.

Task 2: Design a trigger to meet the requirements as stated in the scenario for this
exercise
Design and create a trigger that meets the needs identified in Task 1.

Task 3: Write code to test the behavior of the trigger


Execute data modification statements designed to test that the trigger is working as expected. Results: After this exercise, you should have created a new trigger. Tests should have shown that it is working as expected.

Responding to Data Manipulation via Triggers

15-33

Challenge Exercise 2: Improve the Audit Trigger (Only if time permits)


Scenario
Now that the trigger that was created in Exercise 1 has been deployed to production, the operations team is complaining that too many entries are being audited. Many accounts have more than 10000 as a balance and minor movements of money are causing audit entries. You need to modify the trigger so that only changes in the balance of more than 10000 are audited instead. The main tasks for this exercise are as follows: 1. 2. 3. Modify the trigger based on the updated requirements. Delete all rows from the Marketing.CampaignAudit table. Test the modified trigger.

Task 1: Modify the trigger based on the updated requirements


Review the design of the existing trigger and decide what modifications need to be made to it. Use an ALTER TRIGGER statement to change the existing trigger so that it will meet the updated requirements.

Task 2: Delete all rows from the Marketing.CampaignAudit table


Execute a DELETE statement to remove all existing rows from the Marketing.CampaignAudit table.

Task 3: Test the modified trigger


Execute data modification statements designed to test that the trigger is working as expected. Results: After this exercise, you should have altered the trigger. Tests should show it is now working as expected.

15-34

Implementing a Microsoft SQL Server 2008 R2 Database

Module Review and Takeaways

Review Questions
1. List the module review questions here. Note that the numbers in the numbered list are not auto generated. You will need to enter the numbers manually. Refer to the template instructions for further help. How do constraints and triggers differ regarding timing of execution? Why would you use the UPDATE function rather than the COLUMNS_UPDATED function when designing a trigger?

2. 3.

Best Practices
1. In many business scenarios, it makes sense to mark records as deleted with a status column and use a trigger or stored procedure to update an audit trail table. The changes can then be audited, the data is not lost, and the IT staff can perform purges or archival of the deleted records. Avoid using triggers in situations where constraints could be used instead.

2.

Вам также может понравиться