2016-12-20 3 views
1

Я прошел через множество сообщений на SO. Я понял, что мы можем перечислить все триггеры в одной базе данных.Список всех триггеров из всех баз данных на одном сервере

То, что я хочу, независимо от баз данных, я хочу, чтобы все триггеры данных таблиц accgrp и portinfo

Вот что я пытался

SELECT 
    sysobjects.name AS trigger_name, 
    USER_NAME(sysobjects.uid) AS trigger_owner, 
    s.name AS table_schema, 
    OBJECT_NAME(parent_obj) AS table_name, 
    OBJECTPROPERTY(id, 'ExecIsUpdateTrigger') AS isupdate, 
    OBJECTPROPERTY(id, 'ExecIsDeleteTrigger') AS isdelete, 
    OBJECTPROPERTY(id, 'ExecIsInsertTrigger') AS isinsert, 
    OBJECTPROPERTY(id, 'ExecIsAfterTrigger') AS isafter, 
    OBJECTPROPERTY(id, 'ExecIsInsteadOfTrigger') AS isinsteadof, 
    OBJECTPROPERTY(id, 'ExecIsTriggerDisabled') AS [disabled] 
FROM 
    sysobjects 
INNER JOIN 
    sysusers ON sysobjects.uid = sysusers.uid 
INNER JOIN 
    sys.tables t ON sysobjects.parent_obj = t.object_id 
INNER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id 
WHERE 
    sysobjects.type = 'TR' 
    AND OBJECT_NAME(parent_obj) IN ('accgrp', 'portinfo') 

Я не могу перебрать каждую базу данных и получить список триггеров на этих двух таблицах. У меня есть 50 - 70 баз данных, поэтому каждый раз мне приходится проходить через них вручную. кто-нибудь может предложить что-то по этому поводу.

+1

Есть ли у вас внешняя причина, по которой вы не можете проходить через базы данных, или вы спрашиваете, как проходить через базы данных? Например, вы пробовали динамический SQL и указатель на таблицу sys.databases? –

+0

@HighPlainsGrifter Нет, я не знаю, как написать. Я просто придумал этот sql –

ответ

1

Это даст то, что вы хотите получить

DECLARE @QRY VARCHAR(MAX) =''; 

SELECT @QRY [email protected] + ' select s.name AS table_schema 
    ,OBJECT_NAME(TR.parent_id) AS table_name 
    ,OBJECTPROPERTY(SO.object_id, ''ExecIsUpdateTrigger'') AS isupdate 
    ,OBJECTPROPERTY(SO.object_id, ''ExecIsDeleteTrigger'') AS isdelete 
    ,OBJECTPROPERTY(SO.object_id, ''ExecIsInsertTrigger'') AS isinsert 
    ,OBJECTPROPERTY(SO.object_id, ''ExecIsAfterTrigger'') AS isafter 
    ,OBJECTPROPERTY(SO.object_id, ''ExecIsInsteadOfTrigger'') AS isinsteadof 
    ,OBJECTPROPERTY(SO.object_id, ''ExecIsTriggerDisabled'') AS [disabled] 
FROM ['+name+'].SYS.TRIGGERS TR 
INNER JOIN ['+name+'].sys.tables t  ON TR.parent_id = t.object_id 
INNER JOIN ['+name+'].sys.objects SO ON TR.object_id = SO.object_id 
INNER JOIN ['+name+'].sys.schemas s  ON t.schema_id = s.schema_id 
WHERE OBJECT_NAME(parent_id) IN (''accgrp'',''portinfo'') 
UNION ALL 
' 
FROM SYS.DATABASES 
WHERE name not IN ('master', 'model', 'msdb', 'tempdb', 'resource', 
     'distribution' , 'reportserver', 'reportservertempdb','jiradb') 

SELECT @QRY = SUBSTRING(@QRY,1,LEN(@QRY)-12) 

EXEC(@QRY) 

Что я сделал?

  1. Запрашивается sys.databases Таблица, чтобы создать пользовательские базы данных.
  2. Добавил запрос, взяв базу данных name столбец sys.databases в качестве префикса таблиц. и UNION ALL, как суффикс запроса

  3. Хранится его в переменной @QRY внутренними сквозными с SELECT @QRY [email protected] +

  4. Убран последний UNION ALL с подстроки

  5. Выполненная динамический код.

1
Command sysusers table join and get result : 

SELECT 
sysobjects.name AS trigger_name 
,USER_NAME(sysobjects.uid) AS trigger_owner 
,s.name AS table_schema 
,OBJECT_NAME(parent_obj) AS table_name 
,OBJECTPROPERTY(id, 'ExecIsUpdateTrigger') AS isupdate 
,OBJECTPROPERTY(id, 'ExecIsDeleteTrigger') AS isdelete 
,OBJECTPROPERTY(id, 'ExecIsInsertTrigger') AS isinsert 
,OBJECTPROPERTY(id, 'ExecIsAfterTrigger') AS isafter 
,OBJECTPROPERTY(id, 'ExecIsInsteadOfTrigger') AS isinsteadof 
,OBJECTPROPERTY(id, 'ExecIsTriggerDisabled') AS [disabled] 
FROM sysobjects 
/* 
INNER JOIN sysusers ON sysobjects.uid = sysusers.uid 
*/ 
INNER JOIN sys.tables t ON sysobjects.parent_obj = t.object_id 
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id 
WHERE sysobjects.type = 'TR' 
+0

Будет ли это возвращаться для всех баз данных? – 3N1GM4

+0

вы можете объяснить, что он будет делать. потому что результаты такие же –

+0

Я попытался. Он работает в экземплярах 2005 и 2008 годов. – Mansoor

1

Вот возможный метод с использованием курсора - я добавил ваш скрипт дословно на динамический sql, который запускается на каждой итерации курсора.

SET NOCOUNT ON; 
DECLARE @GET_Databases CURSOR; 
DECLARE 
    @Current_Database NVARCHAR(250) 
    ,@SQL    NVARCHAR(MAX) 
    ,@Param_Declare  NVARCHAR(500) 
    ,@ErrorMsg   NVARCHAR(MAX) 
    ,@LoopCount   INT 
    ,@RowCount   NVARCHAR(5); 

SET @SQL = '' 
SET @Param_Declare = N'@Err NVARCHAR(MAX) OUTPUT,@Rows VARCHAR(5) OUTPUT' 
SET @LoopCount = 1 
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results; 
CREATE TABLE #Results 
(Id   INT IDENTITY(1,1) NOT NULL 
,DatabaseName NVARCHAR(250)  NOT NULL 
,trigger_name NVARCHAR(250)  NOT NULL 
,trigger_owner NVARCHAR(250)  NOT NULL 
,table_schema NVARCHAR(50)  NOT NULL 
,table_name NVARCHAR(250)  NOT NULL 
,isupdate  INT     NOT NULL 
,isdelete  INT     NOT NULL 
,isinsert  INT     NOT NULL 
,isafter  INT     NOT NULL 
,isinsteadof INT     NOT NULL 
,[disabled] INT     NOT NULL 
,Error   NVARCHAR(MAX)   NULL 
); 

SET @GET_Databases = CURSOR FOR 
SELECT name 
FROM sys.databases 
ORDER BY name; 

OPEN @GET_Databases; 

FETCH NEXT FROM @GET_Databases INTO @Current_Database; 
WHILE @@FETCH_STATUS = 0 
BEGIN 
SET @SQL = ''; 
SET @SQL = @SQL + 
---------------------------------------------------------------------------------------------------------------------------------------------- 
---------------------------------------------------------------------------------------------------------------------------------------------- 
'USE ' + QUOTENAME(@Current_Database) + '; 
'; 

---------------------------------------------------------------------------------------------------------------------------------------------- 
---------------------------------------------------------------------------------------------------------------------------------------------- 
    SET @SQL = @SQL + ' 
BEGIN TRY 
    '; 
    SET @SQL = @SQL + 

---------------------------------------------------------------------------------------------------------------------------------------------- 
---------------------------------------------------------------------------------------------------------------------------------------------- 
'INSERT #Results (DatabaseName, trigger_name, trigger_owner, table_schema, table_name, isupdate, isdelete, isinsert, isafter, isinsteadof, disabled) 
SELECT 
    ''' + @Current_Database + ''', 
    sysobjects.name AS trigger_name, 
    USER_NAME(sysobjects.uid) AS trigger_owner, 
    s.name AS table_schema, 
    OBJECT_NAME(parent_obj) AS table_name, 
    OBJECTPROPERTY(id, ''ExecIsUpdateTrigger'') AS isupdate, 
    OBJECTPROPERTY(id, ''ExecIsDeleteTrigger'') AS isdelete, 
    OBJECTPROPERTY(id, ''ExecIsInsertTrigger'') AS isinsert, 
    OBJECTPROPERTY(id, ''ExecIsAfterTrigger'') AS isafter, 
    OBJECTPROPERTY(id, ''ExecIsInsteadOfTrigger'') AS isinsteadof, 
    OBJECTPROPERTY(id, ''ExecIsTriggerDisabled'') AS [disabled] 
FROM 
    sysobjects 
INNER JOIN 
    sysusers ON sysobjects.uid = sysusers.uid 
INNER JOIN 
    sys.tables t ON sysobjects.parent_obj = t.object_id 
INNER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id 
WHERE 
    sysobjects.type = ''TR'' 
    AND OBJECT_NAME(parent_obj) IN (''accgrp'', ''portinfo'')' 
---------------------------------------------------------------------------------------------------------------------------------------------- 
---------------------------------------------------------------------------------------------------------------------------------------------- 
    SET @SQL = @SQL + ' 
    SET @Rows = CONVERT(NVARCHAR(5),@@ROWCOUNT) 
END TRY 
BEGIN CATCH 
    SET @Err = ERROR_MESSAGE(); 
END CATCH'; 

    IF @LoopCount = 1 
    BEGIN 
     PRINT 'Example SQL Script:'; 
     PRINT @SQL; 
    END 

    PRINT @Current_Database; 

    EXECUTE sp_executesql 
     @SQL 
     ,@Param_Declare 
     ,@Err = @ErrorMsg OUTPUT 
     ,@Rows = @RowCount OUTPUT; 

    IF @ErrorMsg IS NOT NULL 
    BEGIN 
     PRINT @ErrorMsg + ' 
'; 
     SET @ErrorMsg = NULL; 
    END 
    ELSE PRINT ' ' + @Rowcount + ' Rows 

'; 
    SET @LoopCount = @LoopCount + 1; 
    FETCH NEXT FROM @GET_Databases INTO @Current_Database; 
END 

CLOSE @GET_Databases; 
DEALLOCATE @GET_Databases; 

SET NOCOUNT OFF; 

SELECT * FROM #Results 

DROP TABLE #Results 
2

Мой запрос работает с diff db-сопоставлениями. Пожалуйста, добавьте дополнительные столбцы, если необходимо:

DECLARE @str  NVARCHAR(MAX) = SPACE(0); 
DECLARE @collation NVARCHAR(MAX) = (SELECT CONVERT(NVARCHAR(MAX), SERVERPROPERTY('COLLATION'))); 
DECLARE @rnd  NVARCHAR(MAX) = NEWID(); 

SELECT 
    @str += CHAR(13) + 'SELECT [trg_name] = [name] COLLATE ' + @collation + ', [db_name] = ' + CHAR(39) + [name] + CHAR(39) + ' FROM [' + [name] + '].[sys].[triggers] ' + CHAR(13) + ' UNION ALL' 
FROM 
    [sys].[databases]; 

SET @str += @rnd; 
SET @str = REPLACE(@str, 'UNION ALL' + @rnd, SPACE(0)); 

EXEC(@str); 
Смежные вопросы