跟踪列更改 - 针对多个目标/表的单个SQL CLR触发器
SQL CLR触发器:
有没有办法从CLR代码中获取目标/表名?
目的:
我正在构建一个通用SQL CLR触发器来跟踪多个表中的列更改。
的信息:
可以将相同的CLR触发器绑定到多个表。
只要CLR触发器绑定到表,无论在CLR触发器属性中指定了什么目标/表,它都会在任何表上触发。这意味着我可以创建1个CLR触发器,并将其用于需要更改跟踪的所有表。
问题在于在Trigger中调用表名/触发器名称标识。 我尝试了所有DMV对象,到目前为止还没有任何解决问题的方法。顺便说一下,无法访问@@ PROCID。
PS:我有一个解决方案,但不能被认为是好的和可靠的。
答案 0 :(得分:0)
提示是将触发目标设置为正确的级别。虽然它不是特定于CLR的,但详细信息可以在MSDN here中找到,但以下内容可能对您有用。
[Microsoft.SqlServer.Server.SqlTrigger (Name="TriggerName", Target="database", Event="FOR UPDATE")]
然后找出更改了哪个表或字段访问SqlXml变量中的EventData。我创建了一个类似于以下类的类,以结构化的方式访问属性。
using System.Data.SqlTypes;
using System.Xml;
using System.Xml.Serialization;
namespace CLRSQLTrigger
{
public class SqlEventData
{
readonly XmlDocument document = new XmlDocument();
public SqlEventData(SqlXml sqlXml)
{
if (sqlXml != SqlXml.Null)
{
document.LoadXml(sqlXml.Value);
}
}
public string EventType
{
get { return document.GetElementsByTagName("EventType")[0].InnerText; }
}
}
}
通过转储在触发事件时返回的SqlXml变量,给定操作接收的值很容易解码。获得这些值后,您可以使用与上面的EventType属性类似的语法,或者直接在代码中使用GetElementsByTagName方法。有100多个事件,每个事件有4-12个字段,所以这部分取决于你。如果你是认真的,有一个不同组合的XSD,但与调试方法相比,它可能会减慢你的速度。 XSD路径将类似于
C:\ Program Files \ Microsoft SQL 服务器\ 100个\工具\ BINN \模式\ SQLSERVER \ 2006年\ 11个\事件
答案 1 :(得分:0)
public partial class Triggers
{
[SqlTrigger(Name = "TriggerName", Target = "TableName", Event = "FOR UPDATE")]
public static void TriggerName ()
{
SqlTriggerContext triggerContext = SqlContext.TriggerContext;
if (triggerContext.TriggerAction == TriggerAction.Update)
{
SqlConnection connection = new SqlConnection("Context Connection=true");
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = "SELECT * FROM INSERTED,DELETED";
connection.Open();
SqlDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
if (SqlContext.TriggerContext.IsUpdatedColumn(reader.GetOrdinal("State")))
{
reader.Read();
long MessageID = Convert.ToInt64(reader["MessageID"]);
int State = Convert.ToInt32(reader["State"]);
reader.Close();
if (State == 1)
FunctionName.SendMassage(MessageID);
}
}
}
}