【问题标题】:SQL Server object version controlSQL Server 对象版本控制
【发布时间】:2015-08-24 03:19:23
【问题描述】:

我们有适用于生产数据库的数据库部署流程。如果存储过程/视图/函数与当前部署不同步,则此过程将更改它们的定义。问题是即使它们没有更改,部署过程也会运行 ALTER 步骤以确保它们是最新的。由于我们有 OLTP 环境,因此在部署期间我们会阻塞存储过程/函数。

我想要实现的只是在定义改变的情况下改变 SP/view/function。

我们已经考虑过对对象定义进行 HashValue 比较(不适用于大定义)、系统表中对象的修改日期比较、SSDT、Redgate SQL 比较/源代码控制。

是否有任何其他方法可以在部署期间用于比较定义,并且仅在更改脚本时才应用更改脚本。

在此先感谢您的意见。

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    您可以利用 SSDT 的架构比较功能。此外,当您在 SSDT 中发布数据库项目时,它会生成一个仅包含差异的脚本。

    请观看http://channel9.msdn.com/Events/Visual-Studio/Launch-2013/VS108的介绍视频

    【讨论】:

    • 感谢您的回答和链接,但不幸的是我们不想使用 SSDT
    • 您能分享一下为什么不使用 SSDT 吗?也许其他 SSDT 用户可以向您学习。
    • 在我们当前的部署过程中,我们不只使用更改脚本并运行整个数据库部署,这就是我不想使用 SSDT 并容纳适合我们现有解决方案的东西的原因。
    【解决方案2】:

    您可以尝试使用以下脚本。
    基本上,它创建了一个Stored Procedure,它作为参数获取对象名称(SP/view/function)和它的alter 命令。存储过程检查“Alter”参数是否会更改现有对象,并且只有当它会运行时才会运行它。

    /****** Object:  StoredProcedure [dbo].[AlterDbObjectIfNecessary]    Script Date: 05/14/2014 09:28:30 ******/
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[AlterDbObjectIfNecessary]') AND type in (N'P', N'PC'))
    DROP PROCEDURE [dbo].[AlterDbObjectIfNecessary]
    GO
    
    
    
    /****** Object:  StoredProcedure [dbo].[AlterDbObjectIfNecessary]    Script Date: 05/14/2014 09:28:30 ******/
    SET ANSI_NULLS ON
    GO
    
    SET QUOTED_IDENTIFIER ON
    GO
    
    -- create new user-toolset relation/ toolset User
    CREATE PROCEDURE [dbo].[AlterDbObjectIfNecessary]
        @alterCommand NVARCHAR(MAX) ,
        @AlteredObjectname NVARCHAR(MAX)
    AS
    BEGIN
    
    
        DECLARE @objId INT
        DECLARE @objName NVARCHAR(max)
        DECLARE @Def nvarchar(max)
    
        --Getting the ID of the object you want to alter
        SELECT
            @objId = id, @objName = o.name
        FROM sysobjects o 
        WHERE   o.type IN ('P', 'TR', 'V', 'TF', 'FN', 'IF')
                AND o.name = @AlteredObjectname
    
    
        --Getting the later definittion
        SELECT @Def = [definition]
        FROM sys.sql_modules 
        WHERE object_id = @objId
    
    
           --print @objName
           --print @def
           SET @def = REPLACE(@def, 'create PROC','alter PROC')
           SET @def = REPLACE(@def, 'create procedure','alter procedure')
           SET @def = REPLACE(@def, 'create function','alter function')
           SET @def = REPLACE(@def, 'create view','alter view')
    
    
        IF UPPER (@def) <> UPPER (@alterCommand)
        BEGIN
            BEGIN TRY   
                --PRINT @alterCommand       
                --Alter the object to new definition
                EXEC sp_executesql @alterCommand
                PRINT @objName + ' Was Modified'
            END TRY
            BEGIN CATCH     
                    PRINT 'Error. Failed to modify ' + @objName + ' : ' + CONVERT(nvarchar(10), ERROR_NUMBER()) + ' ' + ERROR_MESSAGE()
            END CATCH
        END
        ELSE
        BEGIN 
            PRINT 'Modification was not required for ' +@objName
        END
    
    
    END
    GO
    

    您可以通过以下方式使用它:

    DECLARE @alterCommand NVARCHAR(MAX)
    DECLARE @AlteredObjectname NVARCHAR(MAX)
    
    SET @AlteredObjectname = 'MyObjectName' -- <Insert here the name of object you want to alter
    SET @alterCommand = 'ALTER PROCEDURE [dbo].[MyObjectName]
    -- The rest of the alter stattement    
     '
    EXEC AlterDbObjectIfNecessary @AlteredObjectname, @alterCommand
    

    【讨论】:

    • 它的工作就像预期的那样
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2010-10-01
    • 2019-08-10
    • 2012-08-19
    相关资源
    最近更新 更多