2. DDL triggers
DDL (Data Definition Language) triggers were
introduced in SQL Server 2005 as a means of either auditing or
preventing data definition statements. Not to be confused with DML (Data
Manipulation Language) triggers, DDL triggers are defined on events
such as CREATE TABLE. From an auditing perspective, they enable
customized data to be collected for particular events.
Let's walk through a simple example to highlight
the power and flexibility of DDL triggers. Suppose we want to capture
the details related to the creation of new tables, including the T-SQL
statement used to create the table, the user that executed the
statement, and the date and time of the creation. Consider the T-SQL
code in listing 1. We'll first create a table used to store the required details, before creating the DDL trigger that uses the EVENTDATA function to return the required details.
Example 1. DDL trigger to capture table creation details
-- create the table to store the audit details
CREATE TABLE dbo.CREATE_TABLE_LOG (
eventTime datetime
, eventOwner nvarchar(100)
, eventTSQL nvarchar(3000)
)
GO
-- create the DDL trigger
CREATE TRIGGER DDLTrigger_CreateTable ON DATABASE FOR create_table
AS
DECLARE @data XML
SET @data = EVENTDATA()
INSERT INTO CREATE_TABLE_LOG
VALUES (
GETDATE()
, CURRENT_USER
, @data.value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]',
'nvarchar(1000)')
)
GO
|
Listing 1 obtains the T-SQL command from the EVENTDATA function, which returns information about server or database events. As such, it's ideal for use in the body of a DDL trigger.
With the table and trigger in place, a table
creation command will fire the trigger and capture the associated event
data. The results appear in figure 5.
Not only can DDL triggers audit actions, they can also actively prevent certain changes. Consider the example shown in listing 2, which rolls back any attempt to drop or alter a table definition.
Example 2. DDL trigger to prevent table modifications
CREATE TRIGGER DDLTrigger_PreventTableChanges
ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS
PRINT 'Cannot drop or modify tables in this database'
ROLLBACK
|
As listing 2 shows, the ROLLBACK
statement rolls back any attempt to drop or alter any table in the
database in which the trigger is created, along with the error message
"Cannot drop or modify tables in this database."
Similar to DDL triggers, logon triggers, discussed next, enable auditing and control of the logon process.
3. Logon triggers
In a manner similar to creating DDL triggers,
you create a logon trigger to either roll back (deny) a logon or capture
information surrounding the logon using the EVENTDATA function.
Consider the example shown in listing 4, which prevents ReportUser from logging on between 11 p.m. and 11:30 p.m.
Example 4. Logon trigger to prevent logon for a period of time
CREATE TRIGGER validateLogonTrigger
ON ALL SERVER WITH EXECUTE AS 'logonTrigger'
FOR LOGON
AS
BEGIN
DECLARE @time time(0) = getdate()
IF ORIGINAL_LOGIN() = 'ReportUser'
AND @time BETWEEN '23:00:00' and '23:30:00'
ROLLBACK
END
|
With the trigger in place, a logon attempt by
ReportUser between 11 p.m. and 11:30 p.m. will be met with an error
message similar to the one displayed in figure 6.
In closing our coverage of auditing features, let's consider another new feature in SQL Server 2008: Change Data Capture.
4. Change Data Capture
The Change Data Capture (CDC) feature,
introduced in SQL Server 2008, is used to capture data modification
activity in SQL Server tables and make the details of the activity
available in a format that can be used for various purposes.
One of the main uses for CDC is for data
warehousing solutions. The classic data warehouse load process involves
identifying data that has been modified since the last load operation.
Once identified, the data is the subject of an extract, transform, load
(ETL) process.
The challenge for ETL processes is identifying
which data has changed since the last load, and typically involves
timestamp or GUID values along with a corresponding query to select all
data with a timestamp/GUID value greater than the one used in the last
load operation. CDC is perfect for this scenario, as all changes can be
easily consumed, thus avoiding the need for expensive identification
queries.
From an auditing perspective, CDC can be used to
identify modifications to one or more tables. In versions of SQL Server
prior to 2008, such auditing was typically performed using triggers or
some other mechanism. CDC simplifies this process greatly while avoiding
the expensive overhead of a trigger-based approach.
As a brief introduction to how CDC can be used
from an auditing perspective, let's consider an example in which we want
to track modifications to the Production. Product table in the
AdventureWorks2008 database. To do so with CDC, we'll run the code shown
in listing 5.
Example 5. Setting up Change Data Capture
USE [AdventureWorks2008]
GO
-- enable change data capture
EXEC sys.sp_cdc_enable_db
GO
-- enable the Production.Product table for CDC
EXEC sys.sp_cdc_enable_table
@source_schema = N'Production'
, @source_name = N'Product'
, @role_name = N'CDCRole'
GO
|
At this point the table is defined for
CDC. A number of tables and functions are created in the
AdventureWorks2008 database to support CDC, along with two SQL Server
Agent jobs for capturing and cleaning up captured data.