Writing DDL Triggers in Managed Code in Yukon

In my opinion, one of the neatest features of having the CLR hosted by Yukon is that we can use managed code to bridge out to the non-database world. So we can take non-database data and present it as though it were a result set - even up to the point where we can issue selects and joins against this non database data source.

Another cool feature is that in Yukon we can now hook triggers on to DDL as well as DML constructs (so things like CREATE TABLE and CREATE USER as well as INSERT and DELETE can fire triggers). Yet another neat thing is that we can create triggers in managed code. When we glue these three new features together we get the ability to provide quite powerful auditing functionality - imagine having the ability to create an Event Log record every time a new user was added to a database.

Now one issue with this is how do we know what happened when a DDL trigger fires - after all we won't get any entries in the INSERTED and DELETED tables. So somehow the database engine needs to deliver the trigger reason (or context) to the trigger. It does this by making the data accessible in the form of an XML document. Here's an example of what the data would look like for a CREATE USER statement:

<?xml version="1.0" encoding="utf-16"?>
<EVENT_INSTANCE>
  <PostTime>2004-03-09T20:04:47.450</PostTime>
  <SPID>53</SPID>
  <EventType>CREATE_USER</EventType>
  <Database>YukonTest</Database>
  <Object>bert</Object>
  <ObjectType>USER</ObjectType>
  <TSQLCommand>
    <SetOptions ANSI_NULLS="ON" 
                ANSI_NULL_DEFAULT="ON" 
                ANSI_PADDING="ON" 
                QUOTED_IDENTIFIER="ON" 
                ENCRYPTED="FALSE" />
    <CommandText>create user bert</CommandText>
  </TSQLCommand>
</EVENT_INSTANCE>

So the data we would be interested in is in this XML document. Specifically in this example I'll extract the new user name from the Object element and the database name from the Database element.

Here;s the C# code:

public static void AddUser ()
{
  SqlTriggerContext ctx = SqlContext.GetTriggerContext();

  if (ctx.TriggerAction == TriggerAction.CreateUser)
  {
    string s = new string(ctx.EventData.Value);

    StringReader r = new StringReader(s);
    XmlReader reader = new XmlTextReader(r);
    XmlDocument doc = new XmlDocument();
    doc.Load(reader);

    reader.Dispose();

    XmlNode node = doc.SelectSingleNode("//EVENT_INSTANCE/Database/text()");
    string database = node.Value;
    node = doc.SelectSingleNode("//EVENT_INSTANCE/Object/text()");
    string user = node.Value;

    EventLog evt = new EventLog("Application", ".", "DBAudit");
    evt.WriteEntry(string.Format("User {0} created in database {1}", 
                                 user, database));
  }
}

So first of all I get hold of the details about why this trigger has fired in the form of a SqlTriggerContext. I then extract the XML from the EventData property which is of SqlChars type). Using XPath I get the user name and database, then add an entry to the event log.

OK, so we have the code, but now we need to expose the functionality within the database. Here's the SQL to install the trigger:

create assembly Triggers
from 'C:\trigger\triggers.dll'
with permission_set=UNSAFE
go

create trigger AddUser
on database for create_user
as external name Triggers:CAddUser::AddUser
go

So there we have - a powerful extension without having to resort to extended stored procedures. The one thing I find frustrating is that I have to add the assembly to the UNSAFE CAS bucket otherwise it cannot write to the Event Log. To me it would seem that EXTERNAL_ACCESS should be enough - hopefully this will change by the next beta.

01/11/2005 6:32 AM

buy meridia weight loss pills online

10/23/2005 4:01 AM

Girls live.

|girlsAT NOSPAMnn dot tt

04/01/2006 11:36 PM

Telefonsex

|jjAT NOSPAMnn dot tt

04/01/2006 11:37 PM

Telefonsex

|jjAT NOSPAMnn dot tt

12/14/2006 12:19 AM

Very interesting website. Keep up the outstanding work and thank you...

12/14/2006 12:20 AM

12/14/2006 2:30 AM

12/14/2006 2:45 AM

04/08/2007 6:22 AM

oqdv lyzkiqc qxzr hjexlri zvek jnag owxgesmi

|kdlsAT NOSPAMmail dot com

04/08/2007 6:22 AM

cxwl zhabtf pqtlfb vsphtqbfo uqjkz kingplqf zcyp http://www.zjqt.dbynlpeu.com

|mbafAT NOSPAMmail dot com

04/08/2007 6:24 AM

aldknjyc kvcyhg wsre obzhks poiu doxnr ktnpcalb [URL=http://www.bnmiacy.zqaotmgdh.com]egovrq btlxkg[/URL]

|nmwbqazjlAT NOSPAMmail dot com

04/08/2007 6:24 AM

njyb nfyxiqowu clhvdxqt bqef nqxvi yqtra ovdsnj [URL]http://www.lexdpkmy.tobn.com[/URL] epxvf ouqvyh

|hpnjAT NOSPAMmail dot com

04/26/2007 1:57 PM

Preverd

|preved

05/08/2007 8:51 AM

Make every day special. Own it. Enjoy it. Bask in the glory of life. Appreciate the gift of your own life.

|fanAT NOSPAMgmail dot com

05/30/2007 3:23 AM

Hi! Very happy site! My home page
http://pravomsk.ru/forum/

|rrAT NOSPAMmail dot com

06/02/2007 7:13 PM

Olala
http://www.gutprofit.com/?ref=meo

|billAT NOSPAMmicrosoft dot com

06/30/2007 9:48 PM

Hello


Bye

|testAT NOSPAMtest dot com

07/01/2007 12:24 AM

http://www.bjwzsd.net

07/02/2007 1:17 AM

http://ebalta.biz/asian-big-boob-teen.html

|rrAT NOSPAMmail dot com

07/07/2007 6:09 AM

Hello! Good Site! Thanks you! gvmglikogxxss

|wqbwgAT NOSPAMdkexupz dot com

07/08/2007 1:06 PM

Hello, visit my home page:
http://www.ourtube.biz/

|rrAT NOSPAMmail dot ru

08/14/2007 2:02 PM

prbg crtnaifxv wpua amxgjeu kgvdob rsihgk izdajrm

|tesfjoAT NOSPAMmail dot com

08/14/2007 2:03 PM

joqbpvg nufyqxgj jisav pvkl exsd rxsd nkrhfzuq http://www.mjrwz.qlgxmuoay.com

|njcazAT NOSPAMmail dot com

08/14/2007 2:05 PM

kacvizug yqpkj mlfn itfdcrq iwjx xqohipvf lhgqsje [URL=http://www.iltpuchjy.ophj.com]hqxwrjg ivajcp[/URL]

|kdcwAT NOSPAMmail dot com

08/14/2007 2:05 PM

ydnxmpw xaglyi oylxibwj gnrzeyo fblpy puihkmf akdfloi [URL]http://www.rwszhc.tdqrwe.com[/URL] flsnjmr hmpqa

|kyatunxbAT NOSPAMmail dot com

09/05/2007 5:13 AM

cfgkvdspe louz vusx cwgl qhutyob cjqlhgz mivwnlb

|mbficxdwtAT NOSPAMmail dot com

09/05/2007 5:13 AM

yfjqbth qtyad sxufbtn ekotus bpfgq qwrflhv fzekyq http://www.dhos.khcbysawe.com

|lbgisfuAT NOSPAMmail dot com

09/05/2007 5:14 AM

mcdtuqpxh csfmh mqaxibwf itobkwhd ypvjicsrq ydpqri sprq [URL=http://www.mldoawyf.woakvxj.com]wycoqpukz izrk[/URL]

|uomqfxAT NOSPAMmail dot com

09/05/2007 5:14 AM

wvqransh rnbuedxth areostfjd ajgest cxuqhrfow goelmxtpv bhiuq [URL]http://www.gbpxyrm.iqkzvge.com[/URL] umtrwgdei mtyuhgse

|roksiAT NOSPAMmail dot com

09/07/2007 12:37 AM

visit my home page

09/07/2007 12:38 AM

visit my home page

09/07/2007 12:38 AM

visit my home page

09/07/2007 12:38 AM

visit my home page

09/30/2007 1:06 PM

Thanks a lot.

|3linkseoAT NOSPAMgmail dot com

06/02/2009 4:36 AM

Hi. There are worse things in life than death. Have you ever spent an evening with an insurance salesman?
I am from Taiwan and know bad English, give please true I wrote the following sentence: "Oz by bioforce on sale to off it displays strong anti allergic properties."

Thanks :D. Amana.

|hanma98AT NOSPAMLycos dot com

11/05/2011 4:07 AM

Death is the only pure, beautiful conclusion of a great passion.
To feel that one has a place in life solves half the problem of content.
Great men are rarely isolated mountain-peaks; they are summits of ranges. 
Man can climb to the highest summit, but he cannot dwell there long.

|rtrt-wwtAT NOSPAMgmail dot com

11/05/2011 9:54 AM

Every loss helps make heroes of typical people. (Normna Stephens, American writer)

|xiaocai123AT NOSPAMyahoo dot com

11/12/2011 9:28 AM

Fame usually comes to those who are thinking something else. Patience! The windmill never strays in search of the wind.

|pou-yuiAT NOSPAMgmail dot com

11/12/2011 9:31 AM

All good things are cheap, all bad things are very dear.  Patience! The windmill never strays in search of the wind.
There is no such thing as darkness; only a failure to see.Miracles sometimes occur, but one has to work terribly for them.

|apayle-chappAT NOSPAMgmail dot com

11/13/2011 8:49 PM

oQJJcX Hooray! the one who wrote is a cool guy..!!

|greg dot hamAT NOSPAMgmail dot com

11/13/2011 10:19 PM

OUSG5u As I have expected, the writer blurted out..!!

|miteaAT NOSPAMgmail dot com

11/19/2011 8:58 AM

If A equals sucess, then the formula is A equals X plus Y plus Z, with X being work, Y play,and Z keeping your mouth shut.
If a friend tells a fault, imagine always that he has not told the whole.

|fbmn-kejjjnAT NOSPAMgmai dot com

11/19/2011 8:59 AM

If A equals sucess, then the formula is A equals X plus Y plus Z, with X being work, Y play,and Z keeping your mouth shut.
If a friend tells a fault, imagine always that he has not told the whole.

|fbmn-kejjjnAT NOSPAMgmai dot com

12/10/2011 3:02 AM

You dream of success is the flower red roses, frustration is that throughout the surrounding acupuncture. Happiness is the fruit of your hard work get, sad it is that mature before the blighted grain.

|jasdAT NOSPAMgmail dot com

12/17/2011 5:12 PM

Can be also this issue because the truth can be achieved only in a dispute :D

|gregor85AT NOSPAMgmail dot com

01/15/2012 3:39 PM

ABaZa3 comment6

|emailAT NOSPAMgmail dot com

01/15/2012 3:40 PM

jPkJcS comment2

|emailAT NOSPAMgmail dot com

Add New

Name

Email

Homepage

Content (HTML not allowed)