我需要列出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'

我还需要得到表的模式。


当前回答

    CREATE TABLE [dbo].[VERSIONS](
        [ID] [uniqueidentifier] NOT NULL,
        [DATE] [varchar](100) NULL,
        [SERVER] [varchar](100) NULL,
        [DATABASE] [varchar](100) NULL,
        [USER] [varchar](100) NULL,
        [OBJECT] [varchar](100) NULL,
        [ACTION] [varchar](100) NULL,
        [CODE] [varchar](max) NULL,
     CONSTRAINT [PK_VERSIONS] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO

    ALTER TABLE [dbo].[VERSIONS] ADD  CONSTRAINT [DF_VERSIONS_ID]  DEFAULT (newid()) FOR [ID]
    GO


    DROP TRIGGER [DB_VERSIONS_TRIGGER] ON ALL SERVER

    CREATE TRIGGER [DB_VERSIONS_TRIGGER] ON ALL SERVER FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE, 
    CREATE_TRIGGER, ALTER_TRIGGER, DROP_TRIGGER, CREATE_FUNCTION, ALTER_FUNCTION, DROP_FUNCTION, CREATE_VIEW, ALTER_VIEW, 
    DROP_VIEW, CREATE_TABLE, ALTER_TABLE, DROP_TABLE 
    AS 
    SET NOCOUNT ON SET XACT_ABORT OFF; 
    BEGIN 
        TRY 
            DECLARE @DATA XML = EVENTDATA() 
            DECLARE @SERVER VARCHAR(100) = @DATA.value('(EVENT_INSTANCE/ServerName)[1]','VARCHAR(100)') 
            DECLARE @DATABASE VARCHAR(100) = @DATA.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'VARCHAR(100)') 
            DECLARE @USER VARCHAR(100) = @DATA.value('(/EVENT_INSTANCE/LoginName)[1]','VARCHAR(100)') 
            DECLARE @OBJECT VARCHAR(100) = @DATA.value('(EVENT_INSTANCE/ObjectName)[1]','VARCHAR(100)') 
            DECLARE @ACTION VARCHAR(100) = @DATA.value('(/EVENT_INSTANCE/EventType)[1]','VARCHAR(100)') 
            DECLARE @CODE VARCHAR(MAX) = @DATA.value('(/EVENT_INSTANCE//TSQLCommand)[1]','VARCHAR(MAX)' ) 

            IF OBJECT_ID('DB_VERSIONS.dbo.VERSIONS') IS NOT NULL 
            BEGIN 
                INSERT INTO [DB_VERSIONS].[dbo].[VERSIONS]([SERVER], [DATABASE], [USER], [OBJECT], [ACTION], [DATE], [CODE]) VALUES (@SERVER, @DATABASE, @USER, @OBJECT, @ACTION, getdate(), ISNULL(@CODE, 'NA')) 
            END 
        END 
        TRY 
        BEGIN 
            CATCH 
        END 
    CATCH 
    RETURN

其他回答

c# Cribs:我最终得到了这个超级通用的一行程序。希望这对原始海报和/或刚刚输入我在谷歌中做的相同问题的人都有用:

SELECT TriggerRecord.name as TriggerName,ParentRecord.name as ForTableName 
FROM sysobjects TriggerRecord 
INNER JOIN sysobjects ParentRecord ON TriggerRecord.parent_obj=ParentRecord.id 
WHERE TriggerRecord.xtype='TR'

查询特点:

可用于任何SQL数据库(即初始目录) 自我解释 一个简单的陈述 可以直接粘贴到大多数语言的大多数IDE中

我最近有同样的任务,我使用以下sql server 2012 db。使用management studio并连接到要搜索的数据库。然后执行以下脚本。

Select 
[tgr].[name] as [trigger name], 
[tbl].[name] as [table name]

from sysobjects tgr 

join sysobjects tbl
on tgr.parent_obj = tbl.id

WHERE tgr.xtype = 'TR'

如果您正在寻找ALL触发器,请记住MS-SQL有两个基于sql的触发器(sysobjects)。type = 'TR')和基于clr的触发器(sysobjects. type = 'TR')type = 'TA')。

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 

这可能会有所帮助。

SELECT DISTINCT o.[name] AS [Table]
FROM    [sysobjects] o
JOIN    [sysobjects] tr
    ON  o.[id] = tr.[parent_obj]
WHERE   tr.[type] = 'tr'
ORDER BY [Table]

Get a list of tables and all their triggers.

SELECT DISTINCT o.[name] AS [Table], tr.[name] AS [Trigger]
FROM    [sysobjects] o
JOIN    [sysobjects] tr
    ON  o.[id] = tr.[parent_obj]
WHERE   tr.[type] = 'tr'
ORDER BY [Table], [Trigger]