SQL server schema auditing?

前端 未结 4 1995
余生分开走
余生分开走 2021-01-01 05:33

We have a SQL Server 2008 Enterprise database with two different schemas, a locked one that we maintain and an open one that we allow outside development teams to add to and

相关标签:
4条回答
  • 2021-01-01 05:40

    The Redgate options are as follows.

    1) The easiest way you can start auditing schema changes is by installing DLM Dashboard. This is a free tool that alerts and logs all changes using DDL triggers, and will include the information you ask for.

    2) As is already mentioned by Andy Davies, the right way to do this is to start source controlling your schema in the same way as you do for application code. Once you've done this, you can increase your database lifecycle management maturity by including your database in continuous integration and release management practices.

    0 讨论(0)
  • 2021-01-01 05:40

    You could look at putting your database under source control. Perhaps making each outside team take a branch or fork of your database. This gives you auditting of changes via commits and the ability to choose which changes to merge in and/or review/edit those changes before merging in.

    Look at http://www.red-gate.com/products/sql-development/sql-source-control/ for one product that is available.

    Combined with a solution like Github or Bitbucket that open up your source control repositories more directly to external contributors via internet.

    0 讨论(0)
  • 2021-01-01 05:42

    For the second question you can consider triggers as an option. In the following example, information about the event that fired the trigger is captured using the SQL Server’s EVENTDATA() function. The SQL script creates DDL trigger that captures CREATE, ALTER, and DROP events on a database level (although, triggers can be created on the server level to capture events for all databases on the server; ON ALL SERVER option should be used, instead of ON DATABASE)

    CREATE TRIGGER Audit_DDL ON DATABASE
    FOR CREATE_TABLE , ALTER_TABLE , DROP_TABLE
    AS
    DECLARE
    @event xml;
    SET @event = EVENTDATA(
                      );
    INSERT INTO Audit_DDL_Events
    VALUES( REPLACE( CONVERT( varchar( 50
                                 ) , @event.query( 'data(/EVENT_INSTANCE/PostTime)'
                                                 )
                        ) , 'T' , ' '
               ) , 
        CONVERT( varchar( 150
                        ) , @event.query( 'data(/EVENT_INSTANCE/LoginName)'
                                        )
               ) , 
        CONVERT( varchar( 150
                        ) , @event.query( 'data(/EVENT_INSTANCE/UserName)'
                                        )
               ) , 
        CONVERT( varchar( 150
                        ) , @event.query( 'data(/EVENT_INSTANCE/DatabaseName)'
                                        )
               ) , 
        CONVERT( varchar( 150
                        ) , @event.query( 'data(/EVENT_INSTANCE/SchemaName)'
                                        )
               ) , 
        CONVERT( varchar( 150
                        ) , @event.query( 'data(/EVENT_INSTANCE/ObjectName)'
                                        )
               ) , 
        CONVERT( varchar( 150
                        ) , @event.query( 'data(/EVENT_INSTANCE/ObjectType)'
                                        )
               ) , 
        CONVERT( varchar( max
                        ) , @event.query( 'data(/EVENT_INSTANCE/TSQLCommand/CommandText)'
                                        )
               )
      );
    

    An appropriate storage table for the auditing data from EVENTDATA XML must be created also:

    CREATE TABLE Audit_DDL_Events( DDL_Event_Time datetime , 
                               DDL_Login_Name varchar( 150
                                                     ) , 
                               DDL_User_Name varchar( 150
                                                    ) , 
                               DDL_Database_Name varchar( 150
                                                        ) , 
                               DDL_Schema_Name varchar( 150
                                                      ) , 
                               DDL_Object_Name varchar( 150
                                                      ) , 
                               DDL_Object_Type varchar( 150
                                                      ) , 
                               DDL_Command varchar( max
                                                  )
                             );
    
    0 讨论(0)
  • 2021-01-01 05:53

    I've got a system that uses a DDL trigger for exactly this type of thing. It works well enough for my needs. It was originally developed on Sql Server 2005, and now lives on a Sql Server 2008R2 system. It's similar to the one described by the link in Aaron Bertrand's comment.

    Create a table similar to this one.

    CREATE TABLE [dbo].[SchemaLog](
        [SchemaLogID] [int] IDENTITY(1,1) NOT NULL,
        [PostTimeUtc] [datetime] NOT NULL,
        [DatabaseUser] [nvarchar](128) NOT NULL,
        [Event] [nvarchar](128) NOT NULL,
        [Schema] [nvarchar](128) NULL,
        [Object] [nvarchar](128) NULL,
        [TSQL] [nvarchar](max) NOT NULL,
        [XmlEvent] [xml] NOT NULL,
     CONSTRAINT [PK_SchemaLog_1] PRIMARY KEY CLUSTERED 
    (
        [SchemaLogID] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    

    Make sure everyone has insert permissions on the table then create a ddl trigger similar to this.

    CREATE TRIGGER [ddlDatabaseTriggerLog] ON DATABASE  FOR DDL_DATABASE_LEVEL_EVENTS AS  
    BEGIN     
        SET NOCOUNT ON;     
        DECLARE @data XML;     
        DECLARE @schema sysname;     
        DECLARE @object sysname;     
        DECLARE @eventType sysname;     
        SET @data = EVENTDATA();     
        SET @eventType = @data.value('(/EVENT_INSTANCE/EventType)[1]', 'sysname');     
        SET @schema = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname');     
        SET @object = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'sysname')      
        IF @object IS NOT NULL         
            PRINT '  ' + @eventType + ' - ' + @schema + '.' + @object;     
        ELSE         
            PRINT '  ' + @eventType + ' - ' + @schema;     
    
        IF @eventType IS NULL         
            PRINT CONVERT(nvarchar(max), @data);     
    
        INSERT [dbo].[SchemaLog]          (         
            [PostTimeUtc]
        ,          [DatabaseUser]
        ,          [Event]
        ,          [Schema]
        ,          [Object]
        ,          [TSQL]
        ,          [XmlEvent]         )      
        VALUES          (         
            GETUTCDATE()
        ,          CONVERT(sysname, CURRENT_USER)
        ,          @eventType
        ,          CONVERT(sysname, @schema)
        ,          CONVERT(sysname, @object)
        ,          @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(max)')
        ,          @data         ); 
    
    END;
    

    View to select changes in order

    create view SchemaLogOrdered
    as
    SELECT top 10000 *
    FROM            dbo.SchemaLog
    ORDER BY  SchemaLogID DESC
    
    0 讨论(0)
提交回复
热议问题