【问题标题】:Compare stored procedures across multiple databases (SQL Server)跨多个数据库比较存储过程 (SQL Server)
【发布时间】:2010-01-25 16:44:26
【问题描述】:

SQL 大师 --

我们的架构由多个客户数据库和一个通用代码库组成。当我们部署数据库更改时,脚本必须针对每个数据库运行。

由于部署问题,我们的存储过程有时会彼此不同步。我想创建一个脚本来返回这些不匹配的过程,以确保我们在部署后同步了数据库的副本。

是否可以通过让脚本查看两个数据库之间的所有过程并返回不匹配的结果来比较两个或多个数据库?

大意是:

DATABASE_1 | DATABASE_2  | MISMATCHED_PROCEDURE | DATABASE_1_MODIFY_DATE | DATABASE_2_MODIFY_DATE
Customer_1 | Customer_2  | sp_get_names         | 1/1/2010               | 1/2/2010
Customer_1 | Customer_2  | sp_add_person        | 1/5/2010               | 1/6/2010

作为奖励,是否可以通过将最新脚本应用于过期脚本来让脚本自动同步数据库?

非常感谢!

【问题讨论】:

    标签: sql-server tsql synchronization


    【解决方案1】:

    有很多工具可以做到这一点。最好的之一是 Red-Gate SQL 比较。另一个很好的选择是使用 Visual Studio Database Professional 来管理您的数据库架构。除其他外,它会进行非常好的架构比较。

    【讨论】:

    • SQL 比较正是我想到的,很好的建议! red-gate.com/products/SQL_Compare/index.htm
    • 优秀的工具 - 而不仅仅是这个 - Redgate 的一切都是一流的。
    • @marc_s - 同意。 Red-Gate 的几乎所有东西都是黄金。
    【解决方案2】:

    您可以使用下面的脚本识别哪些过程(以及其他稍作修改的对象)不同。

    要同步数据库,您可能想尝试ApexSQL Diff。类似于 Red Gate 的 SQL Compare。

    select S1.name [Db1_Schema], O1.name as [Db1_Object], O1.modify_date,
    S2.name [Db1_Schema], O2.name as [Db1_Object], O2.modify_date
    from database.sys.all_objects O1
    inner join database2.sys.all_objects O2 on O1.name = O2.name
    inner join database.sys.syscomments C1 on O1.object_id = C1.id
    inner join database2.sys.syscomments C2 on O2.object_id = C2.id
    inner join database.sys.schemas S1 on O1.schema_id = S1.schema_id
    inner join database2.sys.schemas S2 on O2.schema_id = S2.schema_id
    where C1.text <> C2.text and
    -- remove the line below if you want to search all objects
    O1.type = 'P' 
    

    【讨论】:

    • 谢谢......它可以工作......但是当我在两个环境中运行时,我得到了更多的记录。每个数据库中有 107 个程序可用,但是当执行上述查询时,我得到了超过 1,00,000 条记录..plz 建议
    • 这段代码告诉我所有的 SP 都是不同的(它们不是),即比较 C1.text C2.text 总是正确的。我从下面的答案中尝试了 object_definition(t1.object_id) object_definition(t2.object_id) 并对其进行了排序
    【解决方案3】:

    如果您没有用于 DB 架构师 (Data Dude) 的 SQL 比较或 Visual Studio 团队系统...试试这个...SQL 2005 及更高版本

    select t1.name,t1.modify_date,t2.modify_date
     from Database1.sys.procedures t1
    join Database2.sys.procedures t2 on t1.name  = t2.name
    and  object_definition(t1.object_id) <>  object_definition(t2.object_id)
    

    【讨论】:

    • 它看起来不错,但我只有当前数据库的定义,尽管在 object_id 之前使用了 db 或别名。来自 Microsoft:“SQL Server 数据库引擎假定 object_id 在当前数据库上下文中。对象定义的排序规则始终与调用数据库上下文的排序规则相匹配。”
    【解决方案4】:

    Red Gate 的 Sql Compare 是完美的解决方案。 但是,如果您负担不起它的成本,有一个非常好的软件免费:Star Inix 的 Sql Compare http://www.starinix.com/sqlcompare02.htm

    【讨论】:

    • 没有完善,但确实是一个不错的小工具...考虑到它是免费的。它对于 dbs 的基本比较做得很好,但必须注意安装时的 cnet 垃圾邮件。
    • 列出的 URL 对我不起作用。但是,URL starinix.com/sqlcompare02.htm 确实有效。
    【解决方案5】:

    使用以下内容:

       SELECT DISTINCT
          o1.name AS Object_Name1,
          o1.type_desc as type_desc1,
          o2.name AS Object_Name2,
          o2.type_desc as type_desc2
       FROM DB1.sys.sql_modules m1
       INNER JOIN DB1.sys.objects o1
       ON m1.object_id = o1.object_id
       FULL OUTER JOIN DB2.sys.sql_modules m2
       INNER JOIN DB2.sys.objects o2
       ON m2.object_id = o2.object_id
       ON o1.name = o2.name
       WHERE isnull(m2.definition,'') <> isnull(m1.definition,'')        
    

    【讨论】:

      【解决方案6】:

      简单的答案,但在所有程序上放置并创建脚本将非常容易和有效。

      【讨论】:

        【解决方案7】:

        是的,RedGate 的东西很棒,但这就是我在比较两个不同数据库中的存储过程时所做的:

        1. 将所有存储过程编写成单独的文件。您可以通过 Microsoft SQL Server Management Studio 向导执行此操作。
        2. 从我与之比较的其他数据库中进行了相同的操作。
        3. 启动了 KDiff3,我相信它是免费的。
        4. 为它提供它需要浏览的两个目录。
        5. 现在双击您看到红色的地方检查您的结果,下面的面板会告诉您差异。

        完成!

        【讨论】:

          【解决方案8】:

          这是切线相关的,但我写了一些东西,提供两个存储过程的文本之间的百分比匹配统计:http://www.sqlservercentral.com/scripts/T-SQL/65787/

          【讨论】:

            【解决方案9】:

            如果要比较两个数据库中的所有存储过程以及另一个数据库中不存在的存储过程的输出名称,请使用以下内容。请注意,这不会只检查存储过程的定义,只是它的名称,但也有一种方法可以检查它。

            -- Declare 2 variable names to hold the name of the databases
            DECLARE @DB1 varchar(50)
            SET @DB1 = 'nameOfDb1'
            DECLARE @DB2 varchar(50)
            SET @DB2 = 'nameOfDb2'
            EXEC('SELECT
                    t1.name,
                    t2.name
                  FROM '
                    + @DB1 +'.sys.procedures t1
                  FULL OUTER JOIN '
                + @DB2 + '.sys.procedures t2
                  on t1.name = t2.name
                  where t1.object_id IS NULL
                  OR t2.object_id IS NULL')
            

            【讨论】:

              【解决方案10】:

              下面的Procedure可以找出两个不同数据库中Functions、Procedures、Triggers的区别。将数据库名称作为参数传递。

              IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE Specific_name = 'SP_SCRIPTDIFF')
              
              DROP PROCEDURE DBO.SP_SCRIPTDIFF
              
              GO
              
              CREATE PROCEDURE [dbo].SP_SCRIPTDIFF
              
              @DBNAME1 SYSNAME, 
              @DBNAME2 SYSNAME
              
              AS
              
              /*
              DATE      : 2016/07/29
              AUTHOR    : SEENI 
              OBJECTIVE : TO COMPARE THE FUNCTIONS, PROCEDURES AND TRIGGERS IN TWO DIFFERENT DATABASES, PASS NAME OF DATABASE1, AND DATABASE2 AS INPUTS.
              */
              
              BEGIN
              
              SET NOCOUNT ON 
              
              Exec ('select  DISTINCT O1.name as [ObjectName], O1.modify_date As DateIn_'+@DBNAME1+',  O2.modify_date As DateIn_'+@DBNAME2+',o1.type as Type from '+
              @DBNAME1+'.sys.all_objects O1 join '+ @DBNAME2+'.sys.all_objects O2 on O1.name = O2.name and  O1.type = O2.type join '+
              @DBNAME1+'.sys.syscomments C1 on O1.object_id = C1.id join '+ @DBNAME2+'.sys.syscomments C2 on O2.object_id = C2.id join '+
              @DBNAME1+'.sys.schemas S1 on O1.schema_id = S1.schema_id join '+ @DBNAME2+'.sys.schemas S2 on O2.schema_id = S2.schema_id
              where C1.text <> C2.text and c1.colid = c2.colid  and O1.Type in (''FN'',''P'',''T'') And o1.Is_Ms_Shipped = 0  Order by O1.type,ObjectName')
              
              RETURN
              
              END 
              
              GO
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-10-21
                • 2019-04-23
                • 2017-02-22
                相关资源
                最近更新 更多