一尘不染

如何保留 SQL Server 存储过程修订的历史记录

sql-server

注意:我不是在询问完整的版本控制。

有什么方法可以自动保留 SQL Server 上存储过程的历史记录。

类似于 Google Docs 自动保存文档版本历史和 Wikipedia 自动保存文章版本历史的方式。

我不希望更新存储过程的用户也必须维护存储过程的存储库。这是太多的工作,人们不会这样做。

希望这是我可以在 SQL Server 中打开的东西......

(我所说的存储过程实际上是指函数、触发器等。基本上一切都在可编程性之下。)


阅读 119

收藏
2022-11-18

共1个答案

一尘不染

虽然我完全同意源代码控制是执行此操作的正确方法,但我也了解并非所有环境都受到足够的约束以单独依赖它(如果有的话),并且有时必须直接进行更改以保留应用程序运行,保存客户端,你有什么。

您可以使用 DDL 触发器将所有修订保存在单独数据库中的表中(当然还要经常备份该数据库)。假设您有一个实用程序数据库:

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

现在在你的数据库中,首先让我们获取我们称之为“初始控制”的东西——存储过程的当前版本:

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;

现在要捕获后续更改,请向数据库添加一个 DDL 触发器:

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

随着时间的推移,查看和比较程序更改、观察新程序添加到系统、查看程序删除以及清楚地了解与谁讨论这些事件将变得很容易。

2022-11-18