2016-12-20 40 views
1

我在SO上經歷了許多帖子。我發現我們可以列出一個數據庫中的所有觸發器。列出一個服務器中所有數據庫的所有觸發器

我要的是不管數據庫我想給定表的所有觸發器accgrpportinfo

這裏是我試過

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

是否存在您無法循環訪問數據庫的外部原因,或者您是否在問如何遍歷數據庫?例如,你是否嘗試過在sys.databases表上使用動態SQL和遊標? –

+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. 通過以sys.databases的數據庫name列作爲表格的前綴來加入查詢。和UNION ALL作爲查詢

  3. 的後綴與SELECT @QRY [email protected] +

  4. 移除的最後一個UNION ALL與子串

  5. 執行的動態代碼存儲在它的可變@QRY通過內部循環。

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

我的查詢使用差異數據庫排序規則。如果需要,請添加更多列以供選擇:

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); 
相關問題