我需要列出SQL Server数据库中的所有触发器表名和表的模式。

我马上就要讲到这个了:

SELECT trigger_name = name, trigger_owner = USER_NAME(uid),table_schema = , table_name = OBJECT_NAME(parent_obj),
  isupdate = OBJECTPROPERTY( id, 'ExecIsUpdateTrigger'), isdelete = OBJECTPROPERTY( id, 'ExecIsDeleteTrigger'),
  isinsert = OBJECTPROPERTY( id, 'ExecIsInsertTrigger'), isafter = OBJECTPROPERTY( id, 'ExecIsAfterTrigger'),
  isinsteadof = OBJECTPROPERTY( id, 'ExecIsInsteadOfTrigger'),
  [disabled] = OBJECTPROPERTY(id, 'ExecIsTriggerDisabled') 
FROM sysobjects INNER JOIN sysusers ON sysobjects.uid = sysusers.uid
WHERE type = 'TR'

我还需要得到表的模式。


当前回答

SELECT 
     sysobjects.name AS trigger_name   ,OBJECT_NAME(parent_obj) AS table_name ,s.name AS table_schema 
    ,USER_NAME(sysobjects.uid) AS trigger_owner 


    ,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' 

这对我很有用

其他回答

这里有一种方法:

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' 

编辑: 注释掉连接到sysusers查询工作在AdventureWorks2008。

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' 

编辑2:用于SQL 2000

SELECT 
     o.name AS trigger_name 
    ,'x' AS trigger_owner 
    /*USER_NAME(o.uid)*/ 
    ,s.name AS table_schema 
    ,OBJECT_NAME(o.parent_obj) AS table_name 
    ,OBJECTPROPERTY(o.id, 'ExecIsUpdateTrigger') AS isupdate 
    ,OBJECTPROPERTY(o.id, 'ExecIsDeleteTrigger') AS isdelete 
    ,OBJECTPROPERTY(o.id, 'ExecIsInsertTrigger') AS isinsert 
    ,OBJECTPROPERTY(o.id, 'ExecIsAfterTrigger') AS isafter 
    ,OBJECTPROPERTY(o.id, 'ExecIsInsteadOfTrigger') AS isinsteadof 
    ,OBJECTPROPERTY(o.id, 'ExecIsTriggerDisabled') AS [disabled] 
FROM sysobjects AS o 
/*
INNER JOIN sysusers 
    ON sysobjects.uid = sysusers.uid 
*/  
INNER JOIN sysobjects AS o2 
    ON o.parent_obj = o2.id 

INNER JOIN sysusers AS s 
    ON o2.uid = s.uid 

WHERE o.type = 'TR'

给你。

    SELECT
    [so].[name] AS [trigger_name],
    USER_NAME([so].[uid]) AS [trigger_owner],
    USER_NAME([so2].[uid]) AS [table_schema],
    OBJECT_NAME([so].[parent_obj]) AS [table_name],
    OBJECTPROPERTY( [so].[id], 'ExecIsUpdateTrigger') AS [isupdate],
    OBJECTPROPERTY( [so].[id], 'ExecIsDeleteTrigger') AS [isdelete],
    OBJECTPROPERTY( [so].[id], 'ExecIsInsertTrigger') AS [isinsert],
    OBJECTPROPERTY( [so].[id], 'ExecIsAfterTrigger') AS [isafter],
    OBJECTPROPERTY( [so].[id], 'ExecIsInsteadOfTrigger') AS [isinsteadof],
    OBJECTPROPERTY([so].[id], 'ExecIsTriggerDisabled') AS [disabled] 
FROM sysobjects AS [so]
INNER JOIN sysobjects AS so2 ON so.parent_obj = so2.Id
WHERE [so].[type] = 'TR'

这里有几件事…

我也看到你试图拉父表的模式信息,我相信为了这样做,你还需要加入sysobjects表本身,这样你就可以正确地获得父表的模式信息。上面的查询可以做到这一点。此外,结果中不需要sysusers表,因此Join已被删除。

使用SQL 2000, SQL 2005和SQL 2008 R2进行测试

一个困难是文本或描述有换行。我的笨拙的拼凑,使它在更表格的东西,是添加一个HTML文字到SELECT子句,复制并粘贴到记事本,保存与HTML扩展,在浏览器中打开,然后复制并粘贴到一个电子表格。 例子

SELECT obj.NAME AS TBL,trg.name,sm.definition,'<br>'
FROM SYS.OBJECTS obj
LEFT JOIN (SELECT trg1.object_id,trg1.parent_object_id,trg1.name FROM sys.objects trg1 WHERE trg1.type='tr' AND trg1.name like 'update%') trg
 ON obj.object_id=trg.parent_object_id
LEFT JOIN (SELECT sm1.object_id,sm1.definition FROM sys.sql_modules sm1 where sm1.definition like '%suser_sname()%') sm ON trg.object_id=sm.object_id
WHERE obj.type='u'
ORDER BY obj.name;

你可能仍然需要使用标签将描述放到一个字段中,但至少它会在一行上,我发现这非常有帮助。

使用这个查询:

SELECT OBJECT_NAME(parent_id) as Table_Name, * FROM [Database_Name].sys.triggers

它既简单又有用。

Necromancing。 只是发布,因为到目前为止所有的解决方案都不够完整。

SELECT 
     sch.name AS trigger_table_schema 
    ,systbl.name AS trigger_table_name 
    ,systrg.name AS trigger_name 
    ,sysm.definition AS trigger_definition 
    ,systrg.is_instead_of_trigger



    -- https://stackoverflow.com/questions/5340638/difference-between-a-for-and-after-triggers
    -- Difference between a FOR and AFTER triggers?
    -- CREATE TRIGGER trgTable on dbo.Table FOR INSERT,UPDATE,DELETE
    -- Is the same as
    -- CREATE TRIGGER trgTable on dbo.Table AFTER INSERT,UPDATE,DELETE
    -- An INSTEAD OF trigger is different, and fires before and instead of the insert 
    -- and can be used on views, in order to insert the appropriate values into the underlying tables.
    -- AFTER specifies that the DML trigger is fired only when all operations 
    -- specified in the triggering SQL statement have executed successfully. 
    -- All referential cascade actions and constraint checks also must succeed before this trigger fires. 
    -- AFTER is the default when FOR is the only keyword specified.
    ,CASE WHEN systrg.is_instead_of_trigger = 1 THEN 0 ELSE 1 END AS is_after_trigger 

    ,systrg.is_not_for_replication 
    ,systrg.is_disabled
    ,systrg.create_date 
    ,systrg.modify_date

    ,CASE WHEN systrg.parent_class = 1 THEN 'TABLE' WHEN systrg.parent_class = 0 THEN 'DATABASE' END trigger_class 


    ,CASE 
        WHEN systrg.[type] = 'TA' then 'Assembly (CLR) trigger'
        WHEN systrg.[type] = 'TR' then 'SQL trigger' 
        ELSE '' 
    END AS trigger_type 

    -- https://dataedo.com/kb/query/sql-server/list-triggers 
    -- ,(CASE WHEN objectproperty(systrg.object_id, 'ExecIsUpdateTrigger') = 1
    --      THEN 'UPDATE ' ELSE '' END 
    -- + CASE WHEN objectproperty(systrg.object_id, 'ExecIsDeleteTrigger') = 1
    --      THEN 'DELETE ' ELSE '' END
    -- + CASE WHEN objectproperty(systrg.object_id, 'ExecIsInsertTrigger') = 1
    --      THEN 'INSERT' ELSE '' END
    -- ) AS trigger_event 

    ,
    ( 
        STUFF 
        ( 
            ( 
                SELECT 
                    ', ' + type_desc AS [text()]
                    -- STRING_AGG(type_desc, ', ') AS foo 
                FROM sys.events AS syse 
                WHERE syse.object_id = systrg.object_id
                FOR XML PATH(''), TYPE 
                -- GROUP BY syse.object_id 
            ).value('.[1]', 'nvarchar(MAX)') 
            , 1, 2, '' 
        ) 
    ) AS trigger_event_groups 

    -- ,CASE WHEN systrg.parent_class = 1 THEN 'TABLE' WHEN systrg.parent_class = 0 THEN 'DATABASE' END trigger_class  

    ,'DROP TRIGGER "' + sch.name + '"."' + systrg.name + '"; ' AS sql 
    -- ,systrg.*
FROM sys.triggers AS systrg 

LEFT JOIN sys.sql_modules AS sysm 
    ON sysm.object_id = systrg.object_id 

-- sys.objects for view triggers 
-- LEFT JOIN sys.objects AS systbl ON systbl.object_id = systrg.object_id 

-- inner join if you only want table-triggers 
LEFT JOIN sys.tables AS systbl ON systbl.object_id = systrg.parent_id 

LEFT JOIN sys.schemas AS sch 
    ON sch.schema_id = systbl.schema_id 

WHERE (1=1) 

-- AND sch.name IS NOT NULL 
-- AND sch.name IS NULL 
-- AND sch.name = 'dbo' 
-- And here, exclude some triggers with a certain naming schema 
/*  
AND 
(
    -- systbl.name IS NULL 
    -- OR 
    NOT 
    (
        systrg.name = 'TRG_' + systbl.name  + '_INSERT_History'
        OR 
        systrg.name = 'TRG_' + systbl.name  + '_UPDATE_History'
        OR 
        systrg.name = 'TRG_' + systbl.name  + '_DELETE_History'
    )
)
*/

ORDER BY 
     sch.name 
    ,systbl.name 
    ,systrg.name