Como manter o histórico de revisões de procedimentos armazenados do SQL Server

22

Nota: Não estou perguntando sobre o controle de versão completa.

Existe alguma maneira automaticamente de manter um histórico de procedimentos armazenados no SQL Server.

Semelhante à maneira como o Google Docs mantém automaticamente um histórico de versões de documentos e a Wikipedia mantém automaticamente um histórico de versões de artigos.

Eu não quero que os usuários que atualizam os procedimentos armazenados também tenham que manter um repositório de procedimentos armazenados. Isso é muito trabalho e as pessoas não o fazem.

Espero que isso seja algo que eu possa ativar no SQL Server ...

(E por procedimentos armazenados realmente quero dizer funções, gatilhos, etc. Basicamente, tudo em Programmability.)

Publiquei em /programming/14522224/how-to-keep-history-of-sql-server-stored-procedure-revisions primeiro porque suspeito que obteria mais visualizações lá.

cja
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Paul White diz GoFundMonica

Respostas:

31

Embora eu esteja plenamente de acordo em que o controle de origem é a maneira correta de fazer isso, também entendo que nem todos os ambientes são disciplinados o suficiente para confiar apenas nisso (se houver), e que às vezes as mudanças precisam ser feitas diretamente para manter o aplicativo executando, salve um cliente, o que você tem.

Você pode usar um gatilho DDL para manter todas as revisões em uma tabela em um banco de dados separado (e, é claro, fazer backup desse banco de dados com freqüência). Supondo que você tenha um banco de dados utilitário:

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

Agora em seu banco de dados, primeiro vamos pegar o que chamaremos de "controle inicial" - a versão atual dos procedimentos armazenados:

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;

Agora, para capturar alterações subseqüentes, adicione um gatilho DDL ao banco de dados:

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

Com o tempo, será fácil ver e comparar as alterações nos procedimentos, assistir novos procedimentos serem adicionados ao sistema, ver os procedimentos serem descartados e ter uma boa idéia de com quem conversar sobre qualquer um desses eventos.

Mais informações aqui:

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

Aaron Bertrand
fonte
2
+1 A maneira mais simples e nativa de fazer isso. Meu palpite é que essa é a resposta que o OP estava procurando.
Thomas Stringer
Sim, esta será a solução para o problema do OP.
Marian
Adoro esta resposta porque, uma vez feita, você obtém o versionamento automático sem nenhum custo adicional. Concordo que não é o mesmo que o Controle de origem, mas é uma valiosa rede de segurança que não deve ser ignorada.
Daniel Williams
2

Eu não acho que haja alguma maneira de manter automaticamente seu código-fonte SQL sob controle de versão. Quero dizer com ferramentas nativas do SQL Server. Eu acho que você pode acabar usando git ou svn, mas a melhor solução para mim foi comprar o Source Control do Red Gate para manter bancos de dados (e procedimentos armazenados) sob controle de versão.

jrara
fonte
1
Claro, um gatilho DDL pode fazer isso sem a necessidade de ferramentas de terceiros (veja minha resposta). É claro que o controle de origem oferece controle e auditoria muito maiores, e as ferramentas de terceiros terão muito mais recursos do que você deseja escrever, mas elas não têm como protegê-lo de mudanças diretas - em outras palavras, elas contam em todos que obedeçam ao protocolo de controle de origem (o que nem sempre é viável).
Aaron Bertrand