Thursday, July 25, 2019

To track user's DDL operations on the database objects

Step 1. First create a table to keep track of all DDL operations by users.

CREATE TABLE [dbo].[DBObjectChangeLog](
[id] [int] IDENTITY(1,1) NOT NULL,
[change_date] [datetime] NOT NULL,
[curr_user] [nvarchar](50) NOT NULL,
[login_user] [nvarchar](50) NOT NULL,
[username] [nvarchar](50) NOT NULL,
[db] [nvarchar](100) NULL,
[event_type] [nvarchar](100) NULL,
[db_object] [nvarchar](100) NULL,
[db_object_type] [nvarchar](100) NULL,
[query] [text] NULL,
 CONSTRAINT [PK_DBObjectChangeLog] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[DBObjectChangeLog] ADD  CONSTRAINT [DF_DBObjectChangeLog_change_date]  DEFAULT (getutcdate()) FOR [change_date]
GO

ALTER TABLE [dbo].[DBObjectChangeLog] ADD  CONSTRAINT [DF_DBObjectChangeLog_curr_user]  DEFAULT (CONVERT([nvarchar](50),user_name(),(0))) FOR [curr_user]
GO

ALTER TABLE [dbo].[DBObjectChangeLog] ADD  CONSTRAINT [DF_DBObjectChangeLog_login_user]  DEFAULT (CONVERT([nvarchar](50),suser_sname(),(0))) FOR [login_user]
GO

ALTER TABLE [dbo].[DBObjectChangeLog] ADD  CONSTRAINT [DF_DBObjectChangeLog_username]  DEFAULT (CONVERT([nvarchar](50),original_login(),(0))) FOR [username]
GO

Step 2. Now make a DDL Trigger

CREATE TRIGGER [trg_DB_object_changeLog]
ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS
AS

DECLARE @event_data XML
SET @event_data = EVENTDATA()

IF @event_data.value('(/EVENT_INSTANCE/EventType)[1]', 'NVARCHAR(100)') not in ('CREATE_STATISTICS','UPDATE_STATISTICS','ALTER_INDEX')

INSERT INTO dbo.DBObjectChangeLog(
event_type, db, db_object, db_object_type, query)
VALUES (
@event_data.value('(/EVENT_INSTANCE/EventType)[1]', 'NVARCHAR(100)'),
@event_data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'NVARCHAR(100)'),
@event_data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(100)'),
@event_data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'NVARCHAR(100)'),
@event_data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'NVARCHAR(MAX)')
)


GO

ENABLE TRIGGER [trg_DB_object_changeLog] ON DATABASE
GO

No comments: