Tải bản đầy đủ (.pdf) (10 trang)

Microsoft SQL Server 2008 R2 Unleashed- P101 ppsx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (361.73 KB, 10 trang )

ptg
944
CHAPTER 29 Creating and Managing User-Defined Functions
Creating and Using CLR Functions
Prior to SQL Server 2005, the only way to extend the functionality of SQL Server beyond
what was available using the T-SQL language was to create extended stored procedures or
Component Object Model (COM) components. The main problem with these types of
extensions was that if not written very carefully, they could have an adverse impact on
the reliability and security of SQL Server. For example, extended stored procedures are
implemented as DLLs that run in the same memory space as SQL Server. An access viola-
tion raised in a poorly written extended stored procedure could crash SQL Server itself.
In addition, neither extended stored procedures nor COM components allow you to create
custom user-defined functions that can be written in any programming language other
than T-SQL, which has a limited command set for operations such as complex string
comparison and manipulation and complex numeric computations.
In SQL Server 2008, you can write custom user-defined functions in any Microsoft .NET
Framework programming language, such as Microsoft Visual Basic .NET or Microsoft
Visual C#. SQL Server supports both scalar and table-valued CLR functions, as well as CLR
user-defined aggregate functions. These extensions written in the CLR are much more
secure and reliable than extended stored procedures or COM components.
For information on the methods and tools to actually create and compile CLR user-
defined functions, see Chapter 46. This chapter focuses only on how to install and use
CLR functions in a SQL Server database.
NOTE
The CLR function examples presented in the following sections are provided as illustra-
tions only. The sample code will not execute successfully because the underlying CLR
assemblies have not been provided.
Adding CLR Functions to a Database
If you’ve already created and compiled a CLR function, your next task is to install that CLR
function in the database. The first step in this process is to copy the .NET assembly to a
location that SQL Server can access, and then you need to load it into SQL Server by creat-


ing an assembly. The syntax for the CREATE ASSEMBLY command is as follows:
CREATE ASSEMBLY AssemblyName [AUTHORIZATION Owner_name]
FROM { <client_assembly_specifier> | <assembly_bits> [ , n ] }
[WITH PERMISSION_SET = (SAFE | EXTERNAL_ACCESS | UNSAFE) ]
AssemblyName is the name of the assembly. client_assembly_specifier specifies the local
path or network location where the assembly being uploaded is located, and also the
manifest filename that corresponds to the assembly. It can be expressed as a fixed string or
an expression evaluating to a fixed string, with variables. The path can be a local path, but
often the path is a network share. assembly_bits is the list of binary values that make up
the assembly and its dependent assemblies.
Download from www.wowebook.com
ptg
945
Creating and Using CLR Functions
29
The WITH clause is optional, and it defaults to SAFE. Marking an assembly with the SAFE
permission set indicates that no external resources (for example, the Registry, Web
services, file I/O) are going to be accessed.
The CREATE ASSEMBLY command fails if it is marked as SAFE and assemblies like System.IO
are referenced. Also, if anything causes a permission demand for executing similar opera-
tions, an exception is thrown at runtime.
Marking an assembly with the EXTERNAL_ACCESS permission set tells SQL Server that it will
use resources such as networking, files, and so forth. Assemblies such as
System.Web.Services (but not System.Web) can be referenced with this set. To create an
EXTERNAL_ACCESS assembly, the creator must have EXTERN ACCESS_permission.
Marking an assembly with the UNSAFE permission set tells SQL Server that not only might
external resources be used, but unmanaged code may be invoked from managed code. An
UNSAFE assembly can potentially undermine the security of either SQL Server or the CLR.
Only members of the sysadmin role can create UNSAFE assemblies.
After the assembly is created, the next step is to associate the method within the assembly

with a user-defined function. You do this with the CREATE FUNCTION command, using the
following syntax:
CREATE FUNCTION [ schema_name. ] function_name
( [ { @parameter_name [AS] [ schema_name.]scalar_datatype [ = default ] }
[ , n ] ] )
RETURNS { return_data_type | TABLE ( { column_name data_type } [ , n ] ) }
[ WITH { [ , RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ]
[ , EXECUTE_AS_Clause ] } ]
[ AS ] EXTERNAL NAME assembly_name.class_name.method_name
After creating the CLR function successfully, you can use it just as you would a T-SQL func-
tion. The following example shows how to manually deploy a table-valued CLR function:
CREATE ASSEMBLY fn_EventLog
FROM ‘F:\assemblies\fn_EventLog\fn_eventlog.dll’
WITH PERMISSION_SET = SAFE
GO
CREATE FUNCTION ShowEventLog(@logname nvarchar(100))
RETURNS TABLE (logTime datetime,
Message nvarchar(4000),
Category nvarchar(4000),
InstanceId bigint)
AS
EXTERNAL NAME fn_EventLog.TabularEventLog.InitMethod
GO
SELECT * FROM dbo.ReadEventLog(N’System’) as T
go
Download from www.wowebook.com
ptg
946
CHAPTER 29 Creating and Managing User-Defined Functions
NOTE

The preceding examples show the steps involved in manually registering an assembly
and creating a CLR function. If you use Visual Studio’s Deploy feature, the
CREATE/ALTER ASSEMBLY and CREATE FUNCTION commands are issued automatically
by Visual Studio. For more details on using Visual Studio to create and deploy user-
defined CLR functions, see Chapter 46.
Deciding Between Using T-SQL or CLR Functions
One question that often comes up regarding user-defined functions is whether it’s better
to develop functions in T-SQL or in the CLR. The answer really depends on the situation
and what the function will be doing.
The general rule of thumb is that if the function will be performing data access or large
set-oriented operations with little or no complex procedural logic, it’s better to create that
function in T-SQL to get the best performance. The reason is that T-SQL works more
closely with the data and doesn’t require multiple transitions between the CLR and SQL
Server engine.
On the other hand, most benchmarks have shown that the CLR performs better than
T-SQL for functions that require a high level of computation or text manipulation. The
CLR offers much richer APIs that provide capabilities not available in T-SQL for opera-
tions such as text manipulation, cryptography, I/O operations, data formatting, and
invoking of web services. For example, T-SQL provides only rudimentary string manipula-
tion capabilities, whereas the .NET Framework supports capabilities such as regular
expressions, which are much more powerful for pattern matching and replacement than
the T-SQL
replace() function.
Another good candidate for CLR functions is user-defined aggregate functions. User-
defined aggregate functions cannot be defined in T-SQL. To compute an aggregate value
over a group in T-SQL, you would have to retrieve the values as a result set and then
enumerate over the result set, using a cursor to generate the aggregate. This results in slow
and complicated code. With CLR user-defined aggregate functions, you need to imple-
ment the code only for the accumulation logic. The query processor manages the itera-
tion, and any user-defined aggregates referenced by the query are automatically

accumulated and returned with the query result set. This approach can be orders of
magnitude faster than using cursors, and it is comparable to using SQL Server built-in
aggregate functions. For example, the following shows how you might use a user-defined
aggregate function that aggregates all the authors for a specific
BookId into a comma-
separated list:
use bigpubs2008
go
SELECT t.Title_ID, count(*), dbo.CommaList(a.au_lname) as AuthorNames
FROM Authors a
JOIN titleauthor ta on a.au_id = ta.au_id
Download from www.wowebook.com
ptg
947
Summary
29
JOIN Titles t on ta.title_id = t.title_id
GROUP BY t.title_id
having count(*) > 2
go
Title_ID AuthorNames

TC7777 O’Leary, Gringlesby, Yokomoto
NOTE
The preceding example will not execute successfully because we have not created the
CommaList() CLR function. It is provided merely as an example showing how such a
function could be used if it was created.
In a nutshell, performance tests have generally shown that T-SQL generally performs
better for standard CRUD (create, read, update, delete) operations, whereas CLR code
performs better for complex math, string manipulation, and other tasks that go beyond

data access.
Summary
User-defined functions in SQL Server 2008 allow you to create reusable routines that can
help make your SQL code more straightforward and efficient.
In this chapter, you saw how to create and modify scalar functions and inline and multi-
statement table-valued functions and how to invoke and use them in queries. Scalar func-
tions can be used to perform more complex operations than those provided by the
built-in scalar functions. Table-valued functions provide a way to create what are essen-
tially parameterized views, and you can include them inline in your queries, just as you
would in a table or view.
With the introduction of CLR-based functions, SQL Server 2008 greatly increases the
power and capabilities of user-defined functions, and CLR functions can also provide
performance improvements over T-SQL functions that need to perform complex computa-
tions or string manipulations.
In the next chapter, you learn how to create and manage triggers in SQL Server 2008.
Download from www.wowebook.com
ptg
This page intentionally left blank
Download from www.wowebook.com
ptg
CHAPTER 30
Creating and Managing
Triggers
IN THIS CHAPTER
. What’s New in Creating and
Managing Triggers
. Using DML Triggers
. Using DDL Triggers
. Using CLR Triggers
. Using Nested Triggers

. Using Recursive Triggers
Atrigger is a special type of stored procedure executed auto-
matically based on the occurrence of a database event. Prior
to SQL Server 2005, the database events that fired triggers
were based only on data manipulations, such as insertions,
updates, or deletions. Triggers in SQL Server 2005 and SQL
Server 2008 can also fire on events related to the definition
of database objects. The two types of triggering events are
referred to as Data Manipulation Language (DML) and Data
Definition Language (DDL) events.
Most of the benefits derived from triggers are based on their
event-driven nature. Once created, triggers automatically
fire (without user intervention) based on an event in the
database. This differs from other database code, which must
be called explicitly in order to execute.
Say, for example, that you would like to keep track of
historical changes to the data in several key tables in a data-
base. Whenever a change is made to the data in the tables,
you would like to put a copy of the data in a historical table
before the change is made. You could accomplish this via
the application code that is making the change to the data.
The application code could copy the data to the history
table before the change occurs and then execute the actual
change. You could also manage this in other ways, such as
by using stored procedures that are called by the applica-
tion and subsequently insert records into the history tables.
These solutions work, but a trigger-based solution has some
distinct advantages over them. With a trigger-based solu-
tion, a trigger can act on any modifications to the key
tables. In the case of the history table example, triggers

would automatically insert records into the history table
whenever a modification was made to the data. This would
Download from www.wowebook.com
ptg
950
CHAPTER 30 Creating and Managing Triggers
all happen within the scope of the original transaction and would write history records for
any changes made to these tables, including ad hoc changes that may have been made
directly to the tables outside the application.
This is just one example of the benefits and uses of triggers. This chapter discusses the
different types of triggers and further benefits they can provide.
What’s New in Creating and Managing Triggers
The features and methods available for creating and managing triggers are essentially the
same in SQL Server 2008 as they were in SQL Server 2005. The upside to this is that you
can take the knowledge and skills that you have with SQL Server 2005 and apply them
directly to SQL Server 2008.
One area that has had some minor changes in SQL Server 2008 relates to events captured
by DDL triggers. In SQL Server 2008 more system stored procedures that perform DDL-like
operations fire DDL triggers and event notification. In SQL Server 2005 certain system
stored procedures would fire DDL triggers, but there are many more included in SQL
Server 2008. For example, the execution of the
sp_rename stored procedure would not fire
a DDL trigger in SQL Server 2005, but it does in SQL Server 2008. Refer to the “Using DDL
Triggers” section later in this chapter for a complete list of DDL statements and system
stored procedures that DDL triggers respond to.
Using DML Triggers
DML triggers are invoked when a DML event occurs in the database. DML events
manipulate or modify the data in a table or view. These events include insertions,
updates, and deletions.
DML triggers are powerful objects for maintaining database integrity and consistency.

They are able to evaluate data before it has been committed to the database. During this
evaluation period, these triggers can perform a myriad of actions, including the following:
. Compare before and after versions of data.
. Roll back invalid modifications.
. Read from other tables, including those in other databases.
. Modify other tables, including those in other databases.
. Execute local and remote stored procedures.
Based on the nature of these actions, triggers were originally used in many cases to
enforce referential integrity. Triggers were used when foreign key columns in one table
had to be validated against primary keys or unique index values in another table. The trig-
gers could fire when data was modified, and validations could be performed to ensure that
referential integrity was maintained.
Download from www.wowebook.com
ptg
951
Using DML Triggers
The advent of declarative referential integrity (DRI) diminished the need for referential
integrity triggers. DRI is now generally implemented with database objects such as foreign
key constraints that perform the referential integrity validation internally. Because of this,
triggers generally handle more complex integrity concepts and enforce restrictions that
cannot be handled through data types, constraints, defaults, or rules. Following are some
examples of trigger uses:
. Maintenance of duplicate and derived data—A denormalized database generally
introduces data duplications (that is, redundancy). Instead of exposing this redun-
dancy to end users and programmers, you can keep the data in sync by using trig-
gers. If the derived data is allowed to be out of sync, you might want to consider
handling refreshes through batch processing or some other method instead.
. Complex column constraints—If a column constraint depends on other rows
within the same table or rows in other tables, using a trigger is the best method for
that column constraint.

. Complex defaults—You can use a trigger to generate default values based on data
in other columns, rows, or tables.
. Inter-database referential integrity—When related tables are found in two differ-
ent databases, you can use triggers to ensure referential integrity across the databases.
You can use stored procedures for all these tasks, but the advantage of using triggers is
that they fire on all data modifications. Stored procedure code or SQL in application code
is executed only when it makes the data modifications. With triggers, all data modifica-
tions are subject to the trigger code, except for bulk copy and a few other nonlogged
actions. Even if a user utilizes an ad hoc tool, such as SQL Server Management Studio
(SSMS) to make changes to the database, the integrity rules cannot be bypassed after the
trigger is in place.
NOTE
Trigge rs and stored procedu res are not mutually ex clusive. You can have bo th triggers
and stored procedures that perform modifications and validation on that same table. If
desired, you can perform some tasks via triggers and other tasks via stored procedures.
Creating DML Triggers
You can create and manage triggers in SQL Server Management Studio or directly via
Transact-SQL (T-SQL) statements. The Object Explorer in SSMS provides a simple means of
creating triggers that you can use to generate the underlying T-SQL code. You expand the
Object Explorer tree to the user table level and then right-click the
Triggers node. When
you select the New Trigger option, as shown in Figure 30.1, the trigger template shown in
the right pane of Figure 30.1 appears.
30
Download from www.wowebook.com
ptg
952
CHAPTER 30 Creating and Managing Triggers
FIGURE 30.1 Using SSMS to create triggers.
You can populate the trigger template by manually editing it, or you can select the Query

menu option Specify Values for Template Parameters. When you select Specify Values for
Template Parameters, a screen appears, allowing you to fill in the basic values for the
trigger, including the table that the trigger will be on and the events to respond to.
You can launch the New Trigger template and other templates related to triggers via the
Template Explorer, which you open by selecting View, Template Explorer in SSMS. Figure
30.2 shows a partial list of the available templates, including those related to triggers.
All the trigger templates provide a basic framework for you to create a trigger, but the core
logic is up to you. Existing triggers or sample triggers are often good alternatives to the
templates because they offer more of the core logic. You can right-click a trigger in the
Object Explorer and select the Script Trigger As option. This option contains several differ-
ent methods to script the trigger. After you script a trigger, you can modify it as necessary
to meet your needs.
TIP
Using the sys.triggers catalog view is a good way to list all the triggers in a data-
base. To use it, you simply open a new query editor window in SSMS and select all the
rows from the view as shown in the following example:
SELECT * FROM sys.triggers
Download from www.wowebook.com
ptg
953
Using DML Triggers
FIGURE 30.2 The Template Explorer.
After you have a basic trigger template, you can code the trigger, with limited restrictions.
Almost every T-SQL statement you would use in a SQL batch or stored procedure is also
available for use in the trigger code. However, you cannot use the following commands in
a DML trigger:
.
ALTER DATABASE
. CREATE DATABASE
. DISK RESIZE

. DROP DATABASE
. LOAD DATABASE and LOAD LOG
. RECONFIGURE
. RESTORE DATABASE and RESTORE LOG
The following sections describe the different types of DML triggers that can be coded and
some of their common uses.
Using AFTER Triggers
An AFTER trigger is the original mechanism that SQL Server created to provide an auto-
mated response to data modifications. Prior to the release of SQL Server 2000, the AFTER
trigger was the only type of trigger, and the word AFTER was rarely used in its name. Any
trigger written for prior versions of SQL Server or documentation referring to these triggers
is for
AFTER triggers.
SQL Server 2000 introduced a new type of trigger called an INSTEAD OF trigger. This trigger
is discussed later in the section titled “INSTEAD OF Triggers.” The introduction of that new
30
Download from www.wowebook.com

×