Без точного понимания, почему вы хотите использовать триггер вместо каждой отдельной таблицы, и что еще вы планируете делать в результирующем коде, кроме вставки предоставленных значений в базовую таблицу (точно так же, как если бы не былоа не триггер вообще) вот что я придумала.Вы заметите, что он сбрасывает триггер, если он уже существует, поэтому вы можете запускать его несколько раз в одной и той же базе данных без ошибок «уже существует».Он игнорирует IDENTITY, ROWGUIDCOL, вычисляемые столбцы и столбцы TIMESTAMP / ROWVERSION.Наконец, в конце я показываю, как можно быстро проверить вместо выполнения (что закомментировано) выходной сценарий (до 8 КБ) и преобразовать его в XML, если вы хотите увидеть больше (до 64 КБ).Нет гарантий, что вы можете вернуть все это в SSMS в зависимости от того, сколько таблиц / столбцов существует.Если вы хотите проверить его и / или запустить вручную, вы можете создать таблицу, в которой будет храниться значение, - тогда вы можете извлечь его с помощью приложения или чего-то еще.Теперь, если вы хотите, чтобы это выполнялось автоматически, вы можете следовать указаниям Юка - сохраните это как хранимую процедуру и создайте триггер DDL, который отвечает на определенные события DDL (CREATE TABLE и т. Д.).
SET NOCOUNT ON;
DECLARE
@cr VARCHAR(2) = CHAR(13) + CHAR(10),
@t VARCHAR(1) = CHAR(9),
@s NVARCHAR(MAX) = N'';
;WITH t AS
(
SELECT [object_id],
s = OBJECT_SCHEMA_NAME([object_id]),
n = OBJECT_NAME([object_id])
FROM sys.tables WHERE is_ms_shipped = 0
)
SELECT @s += 'IF OBJECT_ID(''dbo.ioTrigger_' + t.s + '_' + t.n + ''') IS NOT NULL
DROP TRIGGER [dbo].[ioTrigger_' + t.s + '_' + t.n + '];
G' + 'O
CREATE TRIGGER ioTrigger_' + t.s + '_' + t.n + '
ON ' + QUOTENAME(t.s) + '.' + QUOTENAME(t.n) + '
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
-- surely you must want to put some other code here?
INSERT ' + QUOTENAME(t.s) + '.' + QUOTENAME(t.n) + '
(
' +
(
SELECT @t + @t + name + ',' + @cr
FROM sys.columns AS c
WHERE c.[object_id] = t.[object_id]
AND is_identity = 0
AND is_rowguidcol = 0
AND is_computed = 0
AND system_type_id <> 189
FOR XML PATH(''), TYPE
).value('.[1]', 'NVARCHAR(MAX)') + '--'
+ @cr + @t + ')'
+ @cr + @t + 'SELECT
' +
(
SELECT @t + @t + name + ',' + @cr
FROM sys.columns AS c
WHERE c.[object_id] = t.[object_id]
AND is_identity = 0
AND is_rowguidcol = 0
AND is_computed = 0
AND system_type_id <> 189
FOR XML PATH(''), TYPE
).value('.[1]', 'NVARCHAR(MAX)') + '--'
+ @cr + @t + 'FROM
inserted;
END' + @cr + 'G' + 'O' + @cr
FROM t
ORDER BY t.s, t.n;
SELECT @s = REPLACE(@s, ',' + @cr + '--' + @cr, @cr);
-- you can inspect at least part of the script by running the
-- following in text mode:
SELECT @s;
-- if you want to see more of the whole thing (but not necessarily
-- the whole thing), run this in grid mode and click on result:
SELECT CONVERT(XML, @s);
Несколько предостережений:
1) Я не имею дело с разреженными столбцами, коллекциями xml, файловым потоком и т. Д., Поэтому, если у вас есть необычные таблицы, у вас могут возникнуть сложности с некоторыми из этих функций.
2)имя триггера на самом деле не «защищено» - у вас может быть схема с именем foo, другая схема с именем foo_bar, а затем таблица в foo с именем bar_none и таблица в foo_bar с именем none.Это приведет к дублированию имени триггера, потому что я использую подчеркивание в качестве разделителя.Я жаловался на это с CDC, но они закрыли ошибку, так как не исправят .Просто нужно помнить, если вы используете схемы с подчеркиванием.