Cómo mantener el historial de revisiones de procedimientos almacenados de SQL Server

22

Nota: no estoy preguntando sobre el control completo de la versión.

¿Hay alguna manera automática de mantener un historial de procedimientos almacenados en SQL Server?

Similar a cómo Google Docs mantiene automáticamente un historial de versiones de documentos y Wikipedia mantiene automáticamente un historial de versiones de artículos.

No quiero que los usuarios que actualicen los procedimientos almacenados también tengan que mantener un repositorio de procedimientos almacenados. Esto es demasiado trabajo y la gente no lo hará.

Espero que esto sea algo que pueda activar en SQL Server ...

(Y por procedimientos almacenados realmente me refiero a funciones, disparadores, etc. Básicamente todo en Programabilidad).

Publiqué en /programming/14522224/how-to-keep-history-of-sql-server-stored-procedure-revisions primero porque sospecho que obtendría más vistas allí.

cja
fuente
Los comentarios no son para discusión extendida; Esta conversación se ha movido al chat .
Paul White dice GoFundMonica

Respuestas:

31

Si bien estoy totalmente de acuerdo en que el control de fuente es la forma correcta de hacer esto, también entiendo que no todos los entornos son lo suficientemente disciplinados como para depender solo de eso (si es que lo hacen), y que a veces los cambios deben realizarse directamente para mantener la aplicación corriendo, guardar un cliente, ¿qué tienes?

Puede usar un desencadenador DDL para mantener todas las revisiones en una tabla en una base de datos separada (y, por supuesto, hacer una copia de seguridad de esa base de datos con frecuencia). Suponiendo que tiene una base de datos de utilidades:

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)
);

Ahora en su base de datos, primero tomemos lo que llamaremos "control inicial": la versión actual de los procedimientos almacenados:

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;

Ahora para capturar los cambios posteriores, agregue un desencadenador DDL a la base de datos:

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

Con el tiempo, será fácil ver y comparar los cambios en los procedimientos, ver cómo se agregan nuevos procedimientos al sistema, ver cómo se eliminan los procedimientos y tener una buena idea de con quién hablar sobre cualquiera de estos eventos.

Más información aquí:

http://www.mssqltips.com/sqlservertip/2085/sql-server-ddl-triggers-to-track-all-database-changes/

Aaron Bertrand
fuente
2
+1 La forma más simple y nativa de hacerlo. Supongo que esta es la respuesta que estaba buscando el OP.
Thomas Stringer el
Sí, esta será la solución para el problema de OP.
Marian
Me encanta esta respuesta porque una vez que lo haces, obtienes versiones automáticas sin costo adicional. Estoy de acuerdo en que no es lo mismo que Source Control, pero es una valiosa red de seguridad que no debe ignorarse.
Daniel Williams
2

No creo que haya ninguna manera de mantener automáticamente su Código fuente SQL bajo control de versiones. Me refiero a las herramientas nativas de SQL Server. Creo que podría terminar usando git o svn, pero la mejor solución para mí fue comprar el control de origen de Red Gate para mantener las bases de datos (y los procedimientos almacenados) bajo el control de versiones.

jrara
fuente
1
Claro, un disparador DDL puede hacer esto sin necesidad de herramientas de terceros (ver mi respuesta). Por supuesto, el control de fuente ofrece un control y una auditoría mucho mayores, y las herramientas de terceros tendrán muchas más funciones de las que querrá escribir usted mismo, pero no tienen una forma de protegerlo de los cambios directos; en otras palabras, confían en en todos los que obedecen el protocolo de control de fuente (que no siempre es factible).
Aaron Bertrand