SQL CLR Trigger - получить имя цели / таблицы - PullRequest
2 голосов
/ 27 сентября 2011

Отслеживание изменений столбца - один триггер SQL CLR для нескольких целей / таблиц


Триггер SQL CLR:

Есть лиспособ получить имя цели / таблицы из кода CLR?

Цель:

Я создаю универсальный триггер SQL CLR для отслеживания изменений столбцов в нескольких таблицах.

Информация:

Один и тот же триггер CLR может быть связан с несколькими таблицами.

Пока триггер CLR связан с таблицей, он прекрасно срабатывает на любой таблице независимо от того, какая цель / таблица была указана в атрибуте триггера CLR.Это означает, что я могу создать 1 CLR Trigger и использовать его для всех таблиц, для которых требуется отслеживание изменений.

Проблема заключается в вызове имени таблицы / идентификации имени триггера в Trigger.Я перепробовал все объекты DMV, но пока ничего не решает проблему.Кстати, @@ PROCID недоступен в CLR.

PS: У меня есть решение, но его нельзя считать хорошим и надежным.

Ответы [ 2 ]

0 голосов
/ 16 июля 2017
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); 
                }
            }
        }
    }
0 голосов
/ 21 октября 2011

Подсказка - установить целевой уровень триггера на правильный уровень. Хотя это не относится к CLR, подробности можно найти в MSDN здесь , но следующее, вероятно, будет работать для вас.

[Microsoft.SqlServer.Server.SqlTrigger (Name="TriggerName", Target="database", Event="FOR UPDATE")]

Затем, чтобы выяснить, какую таблицу или поле изменили, обратитесь к EventData, который находится в переменной SqlXml. Я создал класс, подобный следующему, чтобы получить доступ к свойствам структурированным способом.

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 Server \ 100 \ Tools \ Binn \ схемы \ SQLServer \ 2006 \ 11 \ событий

...