Sementara saya setuju sepenuhnya bahwa kontrol sumber adalah cara yang tepat untuk melakukan ini, saya juga mengerti bahwa tidak semua lingkungan cukup disiplin untuk mengandalkan itu saja (jika sama sekali), dan bahwa kadang-kadang perubahan harus dilakukan secara langsung untuk menjaga aplikasi berjalan, menyelamatkan klien, apa pun yang Anda miliki.
Anda bisa menggunakan pemicu DDL untuk menyimpan semua revisi dalam sebuah tabel di basis data yang terpisah (dan tentu saja sering-sering mencadangkan basis data itu). Dengan asumsi Anda memiliki basis data utilitas:
USE Utility;
GO
CREATE TABLE dbo.ProcedureChanges
(
EventDate DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
EventType NVARCHAR(100),
EventDDL NVARCHAR(MAX),
DatabaseName NVARCHAR(255),
SchemaName NVARCHAR(255),
ObjectName NVARCHAR(255),
HostName NVARCHAR(255),
IPAddress VARCHAR(32),
ProgramName NVARCHAR(255),
LoginName NVARCHAR(255)
);
Sekarang dalam database Anda, pertama mari kita ambil apa yang kita sebut "kontrol awal" - versi saat ini dari prosedur tersimpan:
USE YourDB;
GO
INSERT Utility.dbo.ProcedureChanges
(
EventType,
EventDDL,
DatabaseName,
SchemaName,
ObjectName
)
SELECT
N'Initial control',
OBJECT_DEFINITION([object_id]),
DB_NAME(),
OBJECT_SCHEMA_NAME([object_id]),
OBJECT_NAME([object_id])
FROM
sys.procedures;
Sekarang untuk menangkap perubahan selanjutnya, tambahkan pemicu DDL ke database:
USE YourDB;
GO
CREATE TRIGGER CaptureStoredProcedureChanges
ON DATABASE
FOR CREATE_PROCEDURE, ALTER_PROCEDURE, DROP_PROCEDURE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @EventData XML = EVENTDATA(), @ip VARCHAR(32);
SELECT @ip = client_net_address
FROM sys.dm_exec_connections
WHERE session_id = @@SPID;
INSERT Utility.dbo.ProcedureChanges
(
EventType,
EventDDL,
SchemaName,
ObjectName,
DatabaseName,
HostName,
IPAddress,
ProgramName,
LoginName
)
SELECT
@EventData.value('(/EVENT_INSTANCE/EventType)[1]', 'NVARCHAR(100)'),
@EventData.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'NVARCHAR(MAX)'),
@EventData.value('(/EVENT_INSTANCE/SchemaName)[1]', 'NVARCHAR(255)'),
@EventData.value('(/EVENT_INSTANCE/ObjectName)[1]', 'NVARCHAR(255)'),
DB_NAME(), HOST_NAME(), @ip, PROGRAM_NAME(), SUSER_SNAME();
END
GO
Seiring waktu akan menjadi mudah untuk melihat dan membandingkan perubahan pada prosedur, melihat prosedur baru ditambahkan ke sistem, melihat prosedur dibatalkan, dan memiliki ide yang baik tentang siapa yang harus diajak bicara tentang peristiwa-peristiwa ini.
Informasi lebih lanjut di sini:
http://www.mssqltips.com/sqlservertip/2085/sql-server-ddl-triggers-to-track-all-database-changes/