Это изначально не поддерживается и не очень легко сделать sh. На самом деле у меня есть макет, который делает это, но у меня не было времени опубликовать sh. Конечно, не прямо. На данный момент вы можете взглянуть на оба ответа на этот вопрос:
SQL CLR Trigger - получить исходную таблицу
И я обновлю этот ответ, когда Я очистил и опубликовал свое решение.
HOWEVER , в то время как вы говорите, что будет применено только несколько таблиц, имейте в виду, что триггеры выполняются в контекст транзакции, частью которой является оператор DML (или даже DDL). Это имеет два последствия:
- чем дольше длится триггер, тем дольше длится операция DML / DDL, следовательно, дольше удерживаются блокировки на объекте (объектах). Это может оказать неблагоприятное влияние на параллелизм / производительность. Это заставляет многих нервничать из-за того, что операторы DML / DDL ie обращаются к вызовам веб-служб для локальных (intr anet / той же сети) служб, но через inte rnet вводит опасный, сильно изменяющийся риск в процесс это должно быть довольно просто. Конечно, если вы используете Azure VM или Azure SQL Managed Instance, то, возможно, задержка достаточно мала, чтобы этого было «достаточно» безопасно. В любом случае, будьте очень осторожными! (Для ясности: этот риск не снижается при использовании триггера T- SQL для выполнения хранимой процедуры SQLCLR; это все та же транзакция )
- , если триггер не работает / выдает ошибку, по умолчанию которая прервет транзакцию и откатит операцию DML (или DDL). Это намеренное поведение? Обычно отказ регистрировать событие не должен прерывать саму операцию, верно? Поэтому вам, вероятно, потребуется проглотить ошибку (или, по крайней мере, записать ее в текстовый файл, возможно).
Вы должны быть в состоянии отделить операцию DML / DLL от части регистрации, настроив Service Broker для обработки вызова службы регистрации. В этом случае вы должны:
- Использовать триггер T- SQL
- , чтобы получить имя таблицы с помощью:
SELECT tab.[name]
FROM sys.objects tab
WHERE tab.[object_id] = (
SELECT trg.[parent_object_id]
FROM sys.objects trg
WHERE trg.[object_id] = @@PROCID
);
- Соберите любую другую информацию для регистрации возможно из таблиц
INSERTED
и / или DELETED
(после этого у вас не будет доступа к ним; хотя вы можете перепаковать данные в этих двух таблицах как XML, чтобы отправить их как часть сообщения Service Broker - например, SELECT * FROM inserted FOR XML RAW('ins');
) - Поставить в очередь сообщение для Service Broker, включая собранную информацию
- Использование Service Broker
- будет обрабатывать сообщения асинхронно из DML Операции / DLL
- могут выполнять хранимую процедуру SQLCLR, передавая информацию, собранную в триггере T- SQL, для вызова службы регистрации (внутренней или внешней сети)
Имейте в виду (поскольку вы упоминали получение значения PK, на которое влияют, из таблиц INSERTED
и DELETED
), что в этих таблицах может быть несколько строк, если операция DML затрагивала несколько строк (т. Е. никогда предполагает одна строка для работы с DML ations).