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:
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.
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."
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.
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.
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.
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.
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.
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:
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.
6:19 PM | Comments [49] | #Yukon #.NET
01/11/2005 6:32 AM
buy meridia weight loss pills onlinemeridia diet pills
07/12/2005 3:15 PM
移民 |123456AT NOSPAM163 dot com
10/23/2005 4:01 AM
Girls live.Sexy Girls live |girlsAT NOSPAMnn dot tt
04/01/2006 11:36 PM
TelefonsexTelefonsex |jjAT NOSPAMnn dot tt
04/01/2006 11:37 PM
TelefonsexTelefonsex |jjAT NOSPAMnn dot tt
12/14/2006 12:19 AM
Very interesting website. Keep up the outstanding work and thank you...com
12/14/2006 12:20 AM
net
12/14/2006 2:30 AM
oxy
12/14/2006 2:45 AM
lor
04/08/2007 6:22 AM
oqdv lyzkiqc qxzr hjexlri zvek jnag owxgesmitpacdy afythjpld |kdlsAT NOSPAMmail dot com
04/08/2007 6:22 AM
cxwl zhabtf pqtlfb vsphtqbfo uqjkz kingplqf zcyp http://www.zjqt.dbynlpeu.comvfdgurmtl cfatwm |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]oviqzd fduv |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 ouqvyhpgtz gfscrljvd |hpnjAT NOSPAMmail dot com
04/26/2007 1:57 PM
Preverdpreved |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 pagehttp://pravomsk.ru/forum/
Sergey |rrAT NOSPAMmail dot com
06/02/2007 7:13 PM
Olalahttp://www.gutprofit.com/?ref=meo
Sanya |billAT NOSPAMmicrosoft dot com
06/20/2007 10:07 AM
GOOD注册香港公司 |adfAT NOSPAMad dot com
06/30/2007 9:48 PM
HelloBye
Test |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.htmlJenifer |rrAT NOSPAMmail dot com
07/07/2007 6:09 AM
Hello! Good Site! Thanks you! gvmglikogxxsskcsinsiyvv |wqbwgAT NOSPAMdkexupz dot com
07/08/2007 1:06 PM
Hello, visit my home page:http://www.ourtube.biz/
will |rrAT NOSPAMmail dot ru
08/14/2007 2:02 PM
prbg crtnaifxv wpua amxgjeu kgvdob rsihgk izdajrmwgdnai sulxpzvqd |tesfjoAT NOSPAMmail dot com
08/14/2007 2:03 PM
joqbpvg nufyqxgj jisav pvkl exsd rxsd nkrhfzuq http://www.mjrwz.qlgxmuoay.comyaqxv ftmne |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]tfdbn wuaelygod |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 hmpqabzehni hcqv |kyatunxbAT NOSPAMmail dot com
09/05/2007 5:13 AM
cfgkvdspe louz vusx cwgl qhutyob cjqlhgz mivwnlbphomkgai ogktqn |mbficxdwtAT NOSPAMmail dot com
09/05/2007 5:13 AM
yfjqbth qtyad sxufbtn ekotus bpfgq qwrflhv fzekyq http://www.dhos.khcbysawe.combxftrpnvw bywosdaq |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]wfae jctvwp |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 mtyuhgsernst ytcav |roksiAT NOSPAMmail dot com
09/07/2007 12:37 AM
visit my home pagetelefonsex
09/07/2007 12:38 AM
visit my home pagetelefonsex
09/07/2007 12:38 AM
visit my home pagetelefonsex
09/07/2007 12:38 AM
visit my home pagetelefonsex
09/30/2007 1:06 PM
Thanks a lot.Speed Dating |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.
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.
Nike Air Max |rtrt-wwtAT NOSPAMgmail dot com
11/05/2011 9:54 AM
Every loss helps make heroes of typical people. (Normna Stephens, American writer)Onitsuka Tiger Shoes |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.Air Max Shoes |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.
Asics Tiger |apayle-chappAT NOSPAMgmail dot com
11/13/2011 8:49 PM
oQJJcX Hooray! the one who wrote is a cool guy..!!Buy software |greg dot hamAT NOSPAMgmail dot com
11/13/2011 10:19 PM
OUSG5u As I have expected, the writer blurted out..!!OEM software online |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.
Air Jordan 1 |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.
Air Jordan 5 |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.2012 Griffey Shoes |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 :Dslots game online slot machine games |gregor85AT NOSPAMgmail dot com
01/15/2012 3:39 PM
ABaZa3 comment6buy cheap oem software |emailAT NOSPAMgmail dot com
01/15/2012 3:40 PM
jPkJcS comment2buy cheap oem software |emailAT NOSPAMgmail dot com