History of SQL Server - scrappyCoco/SQL-Note GitHub Wiki
For audit purpose we have an ability to track all DDL code, that was submitted to SQL Server. To enable this feature we should create DDL-trigger on the database level.
The tree of available DDL events:
ALTER_SERVER_CONFIGURATION
DDL_EVENTS
| DDL_DATABASE_LEVEL_EVENTS
| | ALTER_DATABASE_SCOPED_CONFIGURATION
| | DDL_ASSEMBLY_EVENTS
| | | ALTER_ASSEMBLY
| | | CREATE_ASSEMBLY
| | | DROP_ASSEMBLY
| | DDL_COLUMN_ENCRYPTION_KEY_EVENTS
| | | ALTER_COLUMN_ENCRYPTION_KEY
| | | CREATE_COLUMN_ENCRYPTION_KEY
| | | DROP_COLUMN_ENCRYPTION_KEY
| | DDL_COLUMN_MASTER_KEY_EVENTS
| | | CREATE_COLUMN_MASTER_KEY
| | | DROP_COLUMN_MASTER_KEY
| | DDL_DATABASE_SECURITY_EVENTS
| | | DDL_APPLICATION_ROLE_EVENTS
| | | | ALTER_APPLICATION_ROLE
| | | | CREATE_APPLICATION_ROLE
| | | | DROP_APPLICATION_ROLE
| | | DDL_ASYMMETRIC_KEY_EVENTS
| | | | ALTER_ASYMMETRIC_KEY
| | | | CREATE_ASYMMETRIC_KEY
| | | | DROP_ASYMMETRIC_KEY
| | | DDL_AUTHORIZATION_DATABASE_EVENTS
| | | | ALTER_AUTHORIZATION_DATABASE
| | | DDL_CERTIFICATE_EVENTS
| | | | ALTER_CERTIFICATE
| | | | CREATE_CERTIFICATE
| | | | DROP_CERTIFICATE
| | | DDL_CRYPTO_SIGNATURE_EVENTS
| | | | ADD_SIGNATURE
| | | | ADD_SIGNATURE_SCHEMA_OBJECT
| | | | DROP_SIGNATURE
| | | | DROP_SIGNATURE_SCHEMA_OBJECT
| | | DDL_DATABASE_AUDIT_EVENTS
| | | | ALTER_AUDIT
| | | | CREATE_AUDIT
| | | | DROP_AUDIT
| | | DDL_DATABASE_AUDIT_SPECIFICATION_EVENTS
| | | | ALTER_DATABASE_AUDIT_SPECIFICATION
| | | | CREATE_DATABASE_AUDIT_SPECIFICATION
| | | | DROP_DATABASE_AUDIT_SPECIFICATION
| | | DDL_DATABASE_ENCRYPTION_KEY_EVENTS
| | | | ALTER_DATABASE_ENCRYPTION_KEY
| | | | CREATE_DATABASE_ENCRYPTION_KEY
| | | | DROP_DATABASE_ENCRYPTION_KEY
| | | DDL_GDR_DATABASE_EVENTS
| | | | DENY_DATABASE
| | | | GRANT_DATABASE
| | | | REVOKE_DATABASE
| | | DDL_MASTER_KEY_EVENTS
| | | | ALTER_MASTER_KEY
| | | | CREATE_MASTER_KEY
| | | | DROP_MASTER_KEY
| | | DDL_ROLE_EVENTS
| | | | ADD_ROLE_MEMBER
| | | | ALTER_ROLE
| | | | CREATE_ROLE
| | | | DROP_ROLE
| | | | DROP_ROLE_MEMBER
| | | DDL_SCHEMA_EVENTS
| | | | ALTER_SCHEMA
| | | | CREATE_SCHEMA
| | | | DROP_SCHEMA
| | | DDL_SYMMETRIC_KEY_EVENTS
| | | | ALTER_SYMMETRIC_KEY
| | | | CREATE_SYMMETRIC_KEY
| | | | DROP_SYMMETRIC_KEY
| | | DDL_USER_EVENTS
| | | | ALTER_USER
| | | | CREATE_USER
| | | | DROP_USER
| | DDL_DEFAULT_EVENTS
| | | BIND_DEFAULT
| | | CREATE_DEFAULT
| | | DROP_DEFAULT
| | | UNBIND_DEFAULT
| | DDL_EVENT_NOTIFICATION_EVENTS
| | | CREATE_EVENT_NOTIFICATION
| | | DROP_EVENT_NOTIFICATION
| | DDL_EXTENDED_PROPERTY_EVENTS
| | | ALTER_EXTENDED_PROPERTY
| | | CREATE_EXTENDED_PROPERTY
| | | DROP_EXTENDED_PROPERTY
| | DDL_FULLTEXT_CATALOG_EVENTS
| | | ALTER_FULLTEXT_CATALOG
| | | CREATE_FULLTEXT_CATALOG
| | | DROP_FULLTEXT_CATALOG
| | DDL_FULLTEXT_STOPLIST_EVENTS
| | | ALTER_FULLTEXT_STOPLIST
| | | CREATE_FULLTEXT_STOPLIST
| | | DROP_FULLTEXT_STOPLIST
| | DDL_FUNCTION_EVENTS
| | | ALTER_FUNCTION
| | | CREATE_FUNCTION
| | | DROP_FUNCTION
| | DDL_PARTITION_EVENTS
| | | DDL_PARTITION_FUNCTION_EVENTS
| | | | ALTER_PARTITION_FUNCTION
| | | | CREATE_PARTITION_FUNCTION
| | | | DROP_PARTITION_FUNCTION
| | | DDL_PARTITION_SCHEME_EVENTS
| | | | ALTER_PARTITION_SCHEME
| | | | CREATE_PARTITION_SCHEME
| | | | DROP_PARTITION_SCHEME
| | DDL_PLAN_GUIDE_EVENTS
| | | ALTER_PLAN_GUIDE
| | | CREATE_PLAN_GUIDE
| | | DROP_PLAN_GUIDE
| | DDL_PROCEDURE_EVENTS
| | | ALTER_PROCEDURE
| | | CREATE_PROCEDURE
| | | DROP_PROCEDURE
| | DDL_RULE_EVENTS
| | | BIND_RULE
| | | CREATE_RULE
| | | DROP_RULE
| | | UNBIND_RULE
| | DDL_SEARCH_PROPERTY_LIST_EVENTS
| | | ALTER_SEARCH_PROPERTY_LIST
| | | CREATE_SEARCH_PROPERTY_LIST
| | | DROP_SEARCH_PROPERTY_LIST
| | DDL_SECURITY_POLICY_EVENTS
| | | ALTER_SECURITY_POLICY
| | | CREATE_SECURITY_POLICY
| | | DROP_SECURITY_POLICY
| | DDL_SEQUENCE_EVENTS
| | | ALTER_SEQUENCE
| | | CREATE_SEQUENCE
| | | DROP_SEQUENCE
| | DDL_SSB_EVENTS
| | | DDL_BROKER_PRIORITY_EVENTS
| | | | ALTER_BROKER_PRIORITY
| | | | CREATE_BROKER_PRIORITY
| | | | DROP_BROKER_PRIORITY
| | | DDL_CONTRACT_EVENTS
| | | | CREATE_CONTRACT
| | | | DROP_CONTRACT
| | | DDL_MESSAGE_TYPE_EVENTS
| | | | ALTER_MESSAGE_TYPE
| | | | CREATE_MESSAGE_TYPE
| | | | DROP_MESSAGE_TYPE
| | | DDL_QUEUE_EVENTS
| | | | ALTER_QUEUE
| | | | CREATE_QUEUE
| | | | DROP_QUEUE
| | | DDL_REMOTE_SERVICE_BINDING_EVENTS
| | | | ALTER_REMOTE_SERVICE_BINDING
| | | | CREATE_REMOTE_SERVICE_BINDING
| | | | DROP_REMOTE_SERVICE_BINDING
| | | DDL_ROUTE_EVENTS
| | | | ALTER_ROUTE
| | | | CREATE_ROUTE
| | | | DROP_ROUTE
| | | DDL_SERVICE_EVENTS
| | | | ALTER_SERVICE
| | | | CREATE_SERVICE
| | | | DROP_SERVICE
| | DDL_SYNONYM_EVENTS
| | | CREATE_SYNONYM
| | | DROP_SYNONYM
| | DDL_TABLE_VIEW_EVENTS
| | | DDL_INDEX_EVENTS
| | | | ALTER_FULLTEXT_INDEX
| | | | ALTER_INDEX
| | | | CREATE_FULLTEXT_INDEX
| | | | CREATE_INDEX
| | | | CREATE_SPATIAL_INDEX
| | | | CREATE_XML_INDEX
| | | | DROP_FULLTEXT_INDEX
| | | | DROP_INDEX
| | | DDL_STATISTICS_EVENTS
| | | | CREATE_STATISTICS
| | | | DROP_STATISTICS
| | | | UPDATE_STATISTICS
| | | DDL_TABLE_EVENTS
| | | | ALTER_TABLE
| | | | CREATE_TABLE
| | | | DROP_TABLE
| | | DDL_VIEW_EVENTS
| | | | ALTER_VIEW
| | | | CREATE_VIEW
| | | | DROP_VIEW
| | DDL_TRIGGER_EVENTS
| | | ALTER_TRIGGER
| | | CREATE_TRIGGER
| | | DROP_TRIGGER
| | DDL_TYPE_EVENTS
| | | CREATE_TYPE
| | | DROP_TYPE
| | DDL_XML_SCHEMA_COLLECTION_EVENTS
| | | ALTER_XML_SCHEMA_COLLECTION
| | | CREATE_XML_SCHEMA_COLLECTION
| | | DROP_XML_SCHEMA_COLLECTION
| | RENAME
| DDL_SERVER_LEVEL_EVENTS
| | ALTER_INSTANCE
| | DDL_AVAILABILITY_GROUP_EVENTS
| | | ALTER_AVAILABILITY_GROUP
| | | CREATE_AVAILABILITY_GROUP
| | | DROP_AVAILABILITY_GROUP
| | DDL_DATABASE_EVENTS
| | | ALTER_DATABASE
| | | CREATE_DATABASE
| | | DROP_DATABASE
| | DDL_ENDPOINT_EVENTS
| | | ALTER_ENDPOINT
| | | CREATE_ENDPOINT
| | | DROP_ENDPOINT
| | DDL_EVENT_SESSION_EVENTS
| | | ALTER_EVENT_SESSION
| | | CREATE_EVENT_SESSION
| | | DROP_EVENT_SESSION
| | DDL_EXTENDED_PROCEDURE_EVENTS
| | | CREATE_EXTENDED_PROCEDURE
| | | DROP_EXTENDED_PROCEDURE
| | DDL_LINKED_SERVER_EVENTS
| | | ALTER_LINKED_SERVER
| | | CREATE_LINKED_SERVER
| | | DDL_LINKED_SERVER_LOGIN_EVENTS
| | | | CREATE_LINKED_SERVER_LOGIN
| | | | DROP_LINKED_SERVER_LOGIN
| | | DROP_LINKED_SERVER
| | DDL_MESSAGE_EVENTS
| | | ALTER_MESSAGE
| | | CREATE_MESSAGE
| | | DROP_MESSAGE
| | DDL_REMOTE_SERVER_EVENTS
| | | ALTER_REMOTE_SERVER
| | | CREATE_REMOTE_SERVER
| | | DROP_REMOTE_SERVER
| | DDL_RESOURCE_GOVERNOR_EVENTS
| | | ALTER_RESOURCE_GOVERNOR_CONFIG
| | | DDL_EXTERNAL_RESOURCE_POOL_EVENTS
| | | | ALTER_EXTERNAL_RESOURCE_POOL
| | | | CREATE_EXTERNAL_RESOURCE_POOL
| | | | DROP_EXTERNAL_RESOURCE_POOL
| | | DDL_RESOURCE_POOL
| | | | ALTER_RESOURCE_POOL
| | | | CREATE_RESOURCE_POOL
| | | | DROP_RESOURCE_POOL
| | | DDL_WORKLOAD_GROUP
| | | | ALTER_WORKLOAD_GROUP
| | | | CREATE_WORKLOAD_GROUP
| | | | DROP_WORKLOAD_GROUP
| | DDL_SERVER_SECURITY_EVENTS
| | | ADD_SERVER_ROLE_MEMBER
| | | ALTER_SERVER_ROLE
| | | CREATE_SERVER_ROLE
| | | DDL_AUTHORIZATION_SERVER_EVENTS
| | | | ALTER_AUTHORIZATION_SERVER
| | | DDL_CREDENTIAL_EVENTS
| | | | ALTER_CREDENTIAL
| | | | CREATE_CREDENTIAL
| | | | DROP_CREDENTIAL
| | | DDL_CRYPTOGRAPHIC_PROVIDER_EVENTS
| | | | ALTER_CRYPTOGRAPHIC_PROVIDER
| | | | CREATE_CRYPTOGRAPHIC_PROVIDER
| | | | DROP_CRYPTOGRAPHIC_PROVIDER
| | | DDL_GDR_SERVER_EVENTS
| | | | DENY_SERVER
| | | | GRANT_SERVER
| | | | REVOKE_SERVER
| | | DDL_LOGIN_EVENTS
| | | | ALTER_LOGIN
| | | | CREATE_LOGIN
| | | | DROP_LOGIN
| | | DDL_SERVER_AUDIT_EVENTS
| | | | ALTER_SERVER_AUDIT
| | | | CREATE_SERVER_AUDIT
| | | | DROP_SERVER_AUDIT
| | | DDL_SERVER_AUDIT_SPECIFICATION_EVENTS
| | | | ALTER_SERVER_AUDIT_SPECIFICATION
| | | | CREATE_SERVER_AUDIT_SPECIFICATION
| | | | DROP_SERVER_AUDIT_SPECIFICATION
| | | DDL_SERVICE_MASTER_KEY_EVENTS
| | | | ALTER_SERVICE_MASTER_KEY
| | | DROP_SERVER_ROLE
| | | DROP_SERVER_ROLE_MEMBER
More information about events is available there: DDL Event Groups
All information about event presented in xml, that we could get using EVENTDATA() function. For more information, please, checkout XSD of EVENTDATA
Lets try to create it:
CREATE TABLE dbo.DdlHistory
(
DdlHistoryId BIGINT NOT NULL IDENTITY PRIMARY KEY,
EventType NVARCHAR(128) NOT NULL,
PostTime DATETIME NOT NULL,
LoginName NVARCHAR(128),
UserName NVARCHAR(128),
DatabaseName NVARCHAR(128),
SchemaName NVARCHAR(128),
ObjectName NVARCHAR(128),
ObjectType NVARCHAR(128),
Command NVARCHAR(MAX)
) WITH (DATA_COMPRESSION = PAGE);
GO
CREATE TRIGGER WriteDdlHistory ON DATABASE
FOR DDL_DATABASE_LEVEL_EVENTS AS
BEGIN
SET NOCOUNT ON;
DECLARE @data XML,
@eventType NVARCHAR(128),
@postTime DATETIME,
@loginName NVARCHAR(128),
@userName NVARCHAR(128),
@databaseName NVARCHAR(128),
@schemaName NVARCHAR(128),
@objectName NVARCHAR(128),
@objectType NVARCHAR(128),
@command NVARCHAR(MAX);
SET @data = EVENTDATA();
SET @eventType = @data.value('(/EVENT_INSTANCE/EventType)[1]', 'NVARCHAR(128)');
SET @postTime = @data.value('(/EVENT_INSTANCE/PostTime)[1]', 'DATETIME');
SET @loginName = @data.value('(/EVENT_INSTANCE/LoginName)[1]', 'NVARCHAR(128)');
SET @userName = @data.value('(/EVENT_INSTANCE/UserName)[1]', 'NVARCHAR(128)');
SET @databaseName = @data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'NVARCHAR(128)');
SET @schemaName = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'NVARCHAR(128)');
SET @objectName = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(128)');
SET @objectType = @data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'NVARCHAR(128)');
SET @command = @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'NVARCHAR(MAX)');
INSERT INTO dbo.DdlHistory(EventType, PostTime, LoginName, UserName, DatabaseName, SchemaName, ObjectName, ObjectType, Command)
VALUES (@eventType, @postTime, @loginName, @userName, @databaseName, @schemaName, @objectName, @objectType, @command);
END
To create this trigger in all new databases, you should to create DDL-trigger in the model database.
To compare changes I'm very suggest to use the DataGrip. To compare your should to select two changed cell of column Command
and press CTRL+SHIFT+D