1. Trang chủ
  2. » Công Nghệ Thông Tin

Microsoft SQL Server 2008 R2 Unleashed- P105 ppsx

10 326 0
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 349,23 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

LISTING 30.15 A Server-Scoped DDL Trigger for Logins CREATE TRIGGER tr_LoginAudit ON ALL SERVER FOR CREATE_LOGIN, ALTER_LOGIN, DROP_LOGIN AS PRINT ‘You must disable the tr_LoginAudit tri

Trang 1

This type of trigger is useful for controlling development and production database

envi-ronments It goes beyond the normal security measures and helps manage unwanted

change For development environments, this type of trigger enables the database

adminis-trator to lock down an environment and focus all changes through that person

The previous examples include events scoped at the database level Let’s look at an

example that applies to server-level events The script in Listing 30.15 creates a trigger

scoped at the server level It prevents changes to the server logins When this trigger is

installed, it displays a message and rolls back any login changes that are attempted

LISTING 30.15 A Server-Scoped DDL Trigger for Logins

CREATE TRIGGER tr_LoginAudit

ON ALL SERVER

FOR CREATE_LOGIN, ALTER_LOGIN, DROP_LOGIN

AS

PRINT ‘You must disable the tr_LoginAudit trigger before making login changes’

ROLLBACK

The DDL trigger examples we have looked at thus far have targeted specific events listed

in Table 30.2 These individual events can also be referenced via an event group Event

groups are hierarchical in nature and can be referenced in DDL triggers instead of the

indi-vidual events For example, the table-level trigger from Listing 30.14 can be changed as

shown in Listing 30.16 to accomplish the same result In Listing 30.16, the

DDL_TABLE_EVENTS group reference replaces the individual event references to

CREATE_TABLE, ALTER_TABLE, and DROP_TABLE

LISTING 30.16 An Example of a DDL Trigger Referencing an Event Group

USE [BigPubs2008]

IF EXISTS (SELECT * FROM sys.triggers

WHERE name = N’tr_TableAudit’ AND parent_class=0)

DROP TRIGGER [tr_TableAudit] ON DATABASE

go

CREATE TRIGGER tr_TableAudit

ON DATABASE

FOR DDL_TABLE_EVENTS

AS

PRINT ‘You must disable the TableAudit trigger in

order to change any table in this database’

ROLLBACK

GO

Trang 2

SQL Server Books Online has an excellent diagram listing all the event groups that can be

used to fire DDL triggers Refer to the “DDL Event Groups” topic in Books Online, which

shows the event groups and related DDL events they contain Event groups simplify

administration and allow for auditing at a high level

The DDL trigger examples we have looked at thus far have executed simple print

state-ments To further extend the functionality of DDL triggers, you can code them to capture

event information related to the DDL trigger execution You do this by using the

EVENTDATA function The EVENTDATA function returns an XML string that includes the time

of the event, server process ID (SPID), and type of event that fired the trigger For some

events, additional information, such as the object name or T-SQL statement, is included in

the XML string as well

The EVENTDATA function is essentially the replacement for the inserted and deleted tables

available with DML triggers but not available with DDL triggers It gives you information

you can use to implement an auditing solution that captures changes to a data definition

This function is particularly useful in situations in which you do not want to prevent

changes to your definition, but you want a record of the changes that occur

Listing 30.17 shows an auditing solution with a DDL trigger that utilizes the EVENTDATA

function to capture any changes to indexes in the BigPubs2008 database Several event

data elements are selected from the EVENTDATA XML string and displayed whenever a

change is made to an index

LISTING 30.17 An Example of a DDL Trigger That References an Event Group

CREATE TRIGGER tr_ddl_IndexAudit

ON DATABASE

FOR CREATE_INDEX, ALTER_INDEX, DROP_INDEX

AS

DECLARE @EventData XML

Capture event data from the EVENTDATA function

SET @EventData = EVENTDATA()

Select the auditing info from the XML stream

SELECT @EventData.query (‘’data(/EVENT_INSTANCE/PostTime)’’)

AS [Event Time],

@EventData.query (‘’data(/EVENT_INSTANCE/EventType)’’)

AS [Event Type],

@EventData.query (‘’data(/EVENT_INSTANCE/ServerName)’’)

AS [Server Name],

@EventData.query (‘’data(/EVENT_INSTANCE/TSQLCommand/CommandText)’’)

AS [Command Text]

GO

To test the DDL trigger in Listing 30.17, you can run the following statement to create an

index on the titles table in the BigPubs2008 database:

Trang 3

CREATE NONCLUSTERED INDEX [nc_titles_type] ON [dbo].[titles] ( [type] ASC )

The INDEX CREATE statement completes successfully, and the event-specific information

appears in the Results pane

You can further extend the auditing capabilities of this type of DDL trigger by writing the

results to an audit table This would give you a quick way of tracking changes to database

objects This type of approach dramatically improves change control and reporting on

database changes

NOTE

DDL triggers can also execute managed code based on the CLR This topic is

dis-cussed in the section “Using CLR Triggers,” later in this chapter

Managing DDL Triggers

The administration of DDL triggers is similar to the administration of DML triggers, but

DDL triggers are located in a different part of the Object Explorer tree The reason is that

DDL triggers are scoped at the server or database level, not at the table level Figure 30.3

shows the Object Explorer tree and the nodes related to DDL triggers at both the server

and database levels The tr_TableAudit trigger you created earlier in this chapter is shown

under the Database Triggers node Figure 30.3 shows the options available when you

right-click a database trigger in the Object Explorer tree

FIGURE 30.3 Using SSMS to manage DDL triggers

Trang 4

The DDL triggers scoped at the server level are found in the Triggers node under the

Server Objects node of the Object Explorer tree (The Server Objects node is near the

bottom of Figure 30.3.)

You can obtain information about DDL triggers by using catalog views These views

provide a convenient and flexible means for querying database objects, including DDL

triggers Table 30.3 lists the catalog views that relate to triggers The table includes the

scope of the trigger that the view reports on and a brief description of what it returns

Listing 30.18 shows sample SELECT statements that utilize the catalog views These

state-ments use the sys.triggers and sys.server_triggers views The SELECT against the

sys.triggers table uses a WHERE clause condition that checks the parent_class column to

retrieve only DDL triggers The SELECT from sys.server_triggers does not need a WHERE

clause because it inherently returns only DDL triggers The results of each statement are

shown below each SELECT in the listing

LISTING 30.18 Viewing DDL Triggers with Catalog Views

DATABASE SCOPED DDL TRIGGERS

select left(name,20) ‘Name’, create_date, modify_date, is_disabled

from sys.triggers

where parent_class = 0

TABLE 30.3 Catalog Views for DDL Triggers

Statements with Database-Level Scope

sys.triggers All triggers, including DDL database-scoped triggers

sys.trigger_events All trigger events, including those that fire DDL

database-scoped triggers sys.sql_modules All SQL-defined modules, including trigger definitions

sys.assembly_modules All CLR-defined modules, including database-scoped triggers

Statements with Server-Level Scope

sys.server_triggers Server-scoped DDL triggers

sys.server_trigger_events Events that fire server-scoped triggers

sys.sql_modules DDL trigger definitions for server-scoped triggers

sys.server_assembly_modules CLR trigger definitions for server-scoped triggers

Trang 5

Name create_date modify_date is_disabled

- -

-tr_TableAudit 2009-06-18 12:48:43.140 2009-06-18 12:48:43.140 0

tr_ddl_IndexAudit 2009-06-22 06:35:10.233 2009-06-22 06:35:10.233 0

SERVER SCOPED DDL TRIGGERS

select left(name,20) ‘Name’, create_date, modify_date, is_disabled

from sys.server_triggers

Name create_date modify_date is_disabled

- -

-tr_LoginAudit 2009-06-18 12:13:46.077 2005-06-18 12:13:46.077 0

Using CLR Triggers

CLR triggers are triggers based on the CLR CLR integration, which was added with SQL

Server 2008, allows for database objects (such as triggers) to be coded in one of the

supported NET languages, including Visual Basic NET and C#

The decision to code triggers and other database objects by using the CLR depends on the

type of operations in the trigger Typically, objects that have heavy computations or

require references to objects outside SQL are coded in the CLR Triggers strictly geared

toward database access should continue to be coded in T-SQL

You can code both DDL and DML triggers by using a supported CLR language Generally

speaking, it is much easier to code a CLR trigger in the Visual Studio NET Integrated

Development Environment (IDE), but you can create them outside the IDE as well Visual

Studio NET provides a development environment that offers IntelliSense, debugging

facil-ities, and other user-friendly capabilities that come with a robust IDE The NET

Framework and development environment are discussed in more detail in Chapter 4, “SQL

Server and the NET Framework.”

The following basic steps are required to create a CLR trigger:

1 Create the CLR class You code the CLR class module with references to the

name-spaces required to compile CLR database objects

2 Compile the CLR class into an assembly or a DDL file, using the appropriate

language compiler

3 Load the CLR assembly into SQL Server so that it can be referenced

4 Create the CLR trigger that references the loaded assembly

The following listings provide examples of each of these steps

Trang 6

NOTE

The CLR must be enabled on your server before you can add CLR components The

CLR option is disabled by default To enable the CLR, you use the sp_configure ‘clr

enabled’, 1 T-SQL command followed by the RECONFIGURE command You can also

enable CLR integration by using SQL Server 2008 Surface Area Configuration and then

choosing the Surface Area Configuration for Features and selecting the Enable CLR

Integration option

Listing 30.19 contains C# code that can be used for the first step: creating the CLR class

This simple example selects rows from the inserted table

LISTING 30.19 A CLR Trigger Class Created with C#

using System;

using System.Data;

using System.Data.Sql;

using Microsoft.SqlServer.Server;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using System.Xml;

using System.Text.RegularExpressions;

public class clrtriggertest

{

public static void showinserted()

{

SqlTriggerContext triggContext = SqlContext.TriggerContext;

SqlConnection conn = new SqlConnection (“context connection = true”);

conn.Open();

SqlCommand sqlComm = conn.CreateCommand();

SqlPipe sqlP = SqlContext.Pipe;

SqlDataReader dr;

sqlComm.CommandText = “SELECT pub_id, pub_name from inserted”;

dr = sqlComm.ExecuteReader();

while (dr.Read())

sqlP.Send((string)dr[0] + “, “ + (string)dr[1]);

}

}

The CLR class in Listing 30.19 needs to be compiled so that SQL Server can use it The

compiler for C# is located in the NET Framework path, which is

Trang 7

C:\WINDOWS\Microsoft.NET\Framework\version by default The last part of the path,

version, is the number of the latest version installed on your machine For simplicity’s

sake, you can add the full NET Framework path to your path variable in the Advanced tab

of your System Properties dialog If you add the NET Framework path to your path

vari-able, you can run the executable for the compiler without navigating to that location

You can save the code from Listing 30.19 in a text file named clrtriggertesting.cs

Then you can open a command prompt window and navigate to the folder where you

saved the clrtriggertesting.cs file The command shown in Listing 30.20 compiles the

clrtriggertesting.cs file into clrtriggertesting.dll This command can be run from

any directory if you have added the NET Framework path (for example,

C:\WINDOWS\Microsoft.NET\Framework\v3.5) to your path variable Without the

addi-tional path entry, you need to navigate to the NET Framework path prior to executing

the command

LISTING 30.20 A CLR Trigger Class Compilation

csc /target:library clrtriggertesting.cs

After compiling clrtriggertesting.dll, you need to load the assembly into SQL Server

Listing 30.21 shows the T-SQL command you can execute to create the assembly for

clrtriggertesting.dll

LISTING 30.21 Using CREATE ASSEMBLY in SQL Server

CREATE ASSEMBLY triggertesting

from ‘c:\clrtrigger\clrtriggertesting.dll’

WITH PERMISSION_SET = SAFE

The final step is to create the trigger that references the assembly Listing 30.22 shows the

T-SQL commands to add a trigger on the publishers table in the BigPubs2008 database

LISTING 30.22 Creating a CLR Trigger

CREATE TRIGGER tri_publishers_clr

ON publishers

FOR INSERT

AS

EXTERNAL NAME triggertesting.clrtriggertest.showinserted

Listing 30.23 contains an INSERT statement to the publishers table that fires the newly

created CLR trigger

Trang 8

LISTING 30.23 Using an INSERT Statement to Fire a CLR Trigger

INSERT publishers

(pub_id, pub_name)

values (‘9922’,’Sams Publishing’)

The trigger simply echoes the contents of the inserted table The output from the trigger

based on the insertion in Listing 30.23 is as follows:

9922, Sams Publishing

The tri_publishers trigger demonstrates the basic steps for creating a CLR trigger The

true power of CLR triggers lies in performing more complex calculations, string

manipula-tions and things of this nature that the can be done much more efficiently with CLR

programming languages than they can in T-SQL

NOTE

For more detailed information and examples of CLR triggers, see Chapter 45

Using Nested Triggers

Triggers can be nested up to 32 levels If a trigger changes a table on which another trigger

exists, the second trigger is fired and can then fire a third trigger, and so on If the nesting

level is exceeded, the trigger is canceled, and the transaction is rolled back

The following error message is returned if the nesting level is exceeded:

Server: Msg 217, Level 16, State 1, Procedure ttt2, Line 2

Maximum stored procedure nesting level exceeded (limit 32)

You can disable nested triggers by setting the nested triggers option of sp_configure

to 0 (off):

EXEC sp_configure ‘nested triggers’, 0

GO

RECONFIGURE WITH OVERRIDE

GO

After the nested triggers option is turned off, the only triggers to fire are those that are

part of the original data modification: the top-level triggers If updates to other tables are

made via the top-level triggers, those updates are completed, but the triggers on those

tables do not fire For example, say you have an UPDATE trigger on the jobs table in the

BigPubs2008 database and an UPDATE trigger on the employee table as well The trigger on

the jobs table updates the employee table If an update is made to the jobs table, the jobs

trigger fires and completes the updates on the employee table However, the trigger on the

employee table does not fire

Trang 9

The default configuration is to allow nested triggers, but there are reasons for turning off

the nested triggers option For example, you might want triggers to fire on direct data

modifications but not on modifications that are made by another trigger Say you have a

trigger on every table that updates the audit time You might want the audit time for a

table to be updated by a trigger when that table is being updated directly, but you might

not want the audit date updated on any of the other tables that are part of the nested

trigger executions This can be accomplished by turning off the nested triggers option

Using Recursive Triggers

Recursive triggers were introduced in SQL Server 7.0 If a trigger modifies the same table

where the trigger was created, the trigger does not fire again unless the recursive

trig-gers option is turned on recursive triggers is a database option turned off by default

The first command in the following example checks the setting of recursive triggers

for the BigPubs2008 database, and the second sets recursive triggers to TRUE:

EXEC sp_dboption BigPubs2008, ‘recursive triggers’

EXEC sp_dboption BigPubs2008, ‘recursive triggers’, TRUE

If you turn off nested triggers, recursive triggers are automatically disabled, regardless of

how the database option is set The maximum nesting level for recursive triggers is the

same as for nested triggers: 32 levels

You should use recursive triggers with care It is easy to create an endless loop, as shown

in Listing 30.24, which creates a recursive trigger on a new test table in the BigPubs2008

database

LISTING 30.24 The Error Message Returned for an Endless Loop with Recursive Triggers

The first statement is used to disable the previously created

DDL trigger which would prevent any changes

DISABLE TRIGGER ALL ON DATABASE

EXEC sp_configure ‘nested triggers’, 1

RECONFIGURE WITH OVERRIDE

EXEC sp_dboption BigPubs2008, ‘recursive triggers’, TRUE

CREATE TABLE rk_tr_test (id int IDENTITY)

GO

CREATE TRIGGER rk_tr ON rk_tr_test FOR INSERT

AS INSERT rk_tr_test DEFAULT VALUES

GO

INSERT rk_tr_test DEFAULT VALUES

Server: Msg 217, Level 16, State 1, Procedure rk_tr, Line 2

Maximum stored procedure nesting level exceeded (limit 32)

Trang 10

The recursion described thus far is known as direct recursion Another type of recursion

exists as well: indirect recursion With indirect recursion, a table that has a trigger fires an

update to another table, and that table, in turn, causes an update to happen to the

origi-nal table on which the trigger fired This action causes the trigger on the origiorigi-nal table to

fire again

With indirect recursion, setting the recursive triggers database setting to FALSE does

not prevent the recursion from happening The only way to prevent this type of recursion

is to set the nested triggers setting to FALSE, which, in turn, prevents all recursion

Summary

Triggers are among the most powerful tools for ensuring the quality of data in a database

The range of commands that can be executed from within triggers and their capability to

automatically fire give them a distinct role in defining sound database solutions

Chapter 31, “Transaction Management and the Transaction Log,” looks at the methods for

defining and managing transactions within SQL Server 2008

Ngày đăng: 05/07/2014, 02:20

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

  • Đang cập nhật ...

TÀI LIỆU LIÊN QUAN