N S

Novick Software Management • Design • Programming • Training • Consulting

   

 

 

SQL Server T-SQL User-Defined Function of the Week

See the status of Triggers

Volume 2 Number 7         February 3, 2004

Check out the UDF Frequently Asked Questions at: http://www.novicksoftware.com/UdfOfWeek/UDF_FAQ.htm

To ask a UDF related question or to contribute a UDF, send e-mail to udf@NovickSoftware.com

Sign up for this newsletter at: http://www.novicksoftware.com/UdfOfWeek/UDFofWeekSignup.htm

Transact-SQL User-Defined Functions has been published!  Take a look at it right now!

Over the last few weeks, I've had reason to write a few triggers. They're sort of fun to write because they're kind of difficult to test. You have to make changes to the underlying tables to get them to run. But there are times when you might not want a trigger to run and SQL Server allows them to be disabled an re-enabled with the ALTER TABLE statement. As you turn them on and off, it's possible to loose track of their status and this week's UDF, udf_Tbl_TriggerStatusTAB helps out by showing the current status of triggers on a group of tables that match a table name pattern. The pattern can be omitted to see the status of all triggers. Here's the CREATE FUNCTION script:

SET QUOTED_IDENTIFIER ON

GO

SET ANSI_NULLS ON

GO

 

ALTER  FUNCTION dbo.udf_Tbl_TriggerStatusTAB (

     @TABLENamePattern as sysname = NULL -- Tables to show,

                                         -- NULL for all

) RETURNS TABLE

  -- No schemabinding due to use of system tables.

/*

* Shows the enabled/disabled status of triggers that match

* the table name pattern.  Use NULL for triggers on all tables

* or a pattern for the LIKE operator to match names.

*

* Example:

select * from udf_Tbl_TriggerStatusTAB(null)

*

* History:

* When          Who     Description

* ------------- ------- ----------------------------------------

* 2003-11-10    ASN     Initial Coding

*

* © Copyright 2003 Andrew Novick http://www.NovickSoftware.com

* You may use this function in any of your SQL Server databases

* including databases that you sell, so long as they contain

* other unrelated database objects. You may not publish this

* UDF either in print or electronically.

* Published in the T-SQL UDF of the Week Vol 2 #7 2/3/04

http://www.NovickSoftware.com/UDFofWeek/UDFofWeek.htm

****************************************************************/

AS RETURN

 

    SELECT TOP 100 PERCENT WITH TIES

           T.[name] as TableName

         , TR.[Name] as TriggerName

         , CASE WHEN 1=OBJECTPROPERTY(TR.[id], 'ExecIsTriggerDisabled')

                THEN 'Disabled' ELSE 'Enabled' END Status

         FROM sysobjects T

       

             INNER JOIN sysobjects TR

                  on t.[ID] = TR.parent_obj

         WHERE (T.xtype = 'U' or T.XType = 'V')

            AND (@TableNamePattern IS NULL OR T.[name] LIKE @TableNamePattern)

            AND (TR.xtype = 'TR')

         ORDER BY T.[name]

                , TR.[name]

 

GO

 

GRANT SELECT on udf_TBL_TriggerStatusTAB to PUBLIC

GO

Testing udf_Tbl_TriggerStatus involves creating a trigger and enabling and disabling it. The process involes nine steps so the remaider of this issues is devoted to the script to test it. Each step starts with a comment and ends with a GO so it will be easy to pick them out. The script is available in this link as one file if you want to copy it into Query Analyzer. Here we go...

Start with some cleanup of previous tests:


-- Remove the existing testing table from a previous test
if OBJECT_ID('TriggerTester') is NOT NULL  drop table TriggerTester
SET NOCOUNT ON
PRINT 'Trigger Testing Script'
GO

(Results)
Trigger Testing Script
Now create the TriggerTester table:
-- Create the TriggerTester Table
CREATE TABLE TriggerTester (
          [ID]        int IDENTITY (1,1)  PRIMARY KEY
        , RowDesc     VARCHAR(32) NOT NULL
        , LastUpdated datetime NULL
             )
PRINT 'Table created'
GO

(Results)
Table created

Create the UPDATE trigger:
-- Create the Update trigger 
CREATE TRIGGER TriggerTester_Update_demo on TriggerTester 
          FOR UPDATE
AS

    UPDATE TriggerTester
         SET LastUpdated = GETDATE()
       FROM TriggerTester 
           inner join inserted
               on inserted.[ID] = TriggerTester.[ID]
GO

(Results)
The command(s) completed successfully.
Inser a row. You'll see that LastUpdate is NULL becasue the trigger is an UPDATE trigger and doesn't run.
-- Insert on row into the table and verify that LastUpdate is NULL
PRINT 'Inserting one row into TriggerTester'
INSERT INTO TriggerTester (RowDesc) VALUES ('Test Row')
SELECT *, getdate() NOW FROM TriggerTester
GO
(Results)
Inserting one row into TriggerTester
ID  RowDesc    LastUpdated          NOW                        
--- ---------- -------------------- -------------------------- 
1   Test Row   NULL                 2004-01-30 02:26:50.200   
Update the row to show that the trigger runs:
-- Update and verify that the trigger has run, because LastUpdate shoould
-- be non-Null and the same as NOW
UPDATE TriggerTester  SET RowDesc = 'Test Row Updated'
SELECT *, getdate() NOW FROM TriggerTester
GO

(Results)
ID  RowDesc           LastUpdated              NOW     
--- ----------------- ------------------------ -----------------------
1   Test Row Updated  2004-01-30 02:29:17.403  2004-01-30 02:29:17.403
Show the status of triggers on the table using our UDF of the week.
-- Show the staus of all triggers on the TriggerTester table
SELECT * FROM udf_Tbl_TriggerStatusTAB ('TriggerTester')
GO

(Results)
TableName           TriggerName                    Status   
------------------- ------------------------------ -------- 
TriggerTester       TriggerTester_Update_demo      Enabled
Disable the trigger and show its status with udf_Tbl_TriggerStatusTAB:
-- Disable the Trigger
ALTER TABLE TriggerTester DISABLE TRIGGER TriggerTester_Update_demo
SELECT *  FROM udf_Tbl_TriggerStatusTAB ('TriggerTester%')
GO

(Results)
TableName          TriggerName                    Status   
------------------ ------------------------------ -------- 
TriggerTester      TriggerTester_Update_demo      Disabled
Now that the trigger is disabled, perform an update and see that LastUpdated isn't modified:
-- Perform the update and see that LastUpdated and NOW are different
-- because the trigger was not run
UPDATE TriggerTester SET RowDesc = 'Test Row Updated Again'
SELECT *, getdate() NOW FROM TriggerTester
GO

(Results)
ID  RowDesc                LastUpdated             NOW                    
--- ---------------------- ----------------------- -----------------------
1   Test Row Updated Again 2004-01-30 02:29:17.403 2004-01-30 02:32:36.670
Enable the trigger and verify its status:
-- Enable the trigger
ALTER TABLE TriggerTester ENABLE TRIGGER TriggerTester_Update_demo
SELECT * FROM udf_Tbl_TriggerStatusTAB ('TriggerTester%')
GO

(Results)
TableName       TriggerName                    Status   
--------------- ------------------------------ -------- 
TriggerTester   TriggerTester_Update_demo      Enabled
The nine steps show that our trigger works and that udf_Tbl_TriggerStatusTAB verifies the trigger status correctly. Transact-SQL User-Defined Functions is available on my web site and on Amazon and in many stores.


Do you have a great UDF that you'd like to share?  Or maybe you have a T-SQL problem that you think could be solved by a UDF but you don't know how? Send them to: UDF@NovickSoftware.com

and they might be published in this newsletter.  I try and respond to every request that I get. 

Thanks, 
Andrew Novick


RSS as HTML

Personal Blog

 
New Tips:

Loading SQL Profiler trace (.trc) files with fn_trace_gettrace

Upcoming
Presentations:

Big Data:
Working with Terabytes
in SQL Server

July 9 '08

Nov 19-21
SQL Pass 2008


Full Schedule