web-dev-qa-db-ja.com

複数のデータベース間でストアドプロシージャを比較する(SQL Server)

SQLの達人-

私たちのアーキテクチャは、共通のコードベースに対する複数の顧客データベースで構成されています。データベースの変更をデプロイするときは、スクリプトを各データベースに対して実行する必要があります。

デプロイメントの問題のために、ストアドプロシージャが互いに同期しなくなる場合があります。これらの不一致のプロシージャを返すスクリプトを作成して、展開後にデータベースのコピーを同期したことを確認したいと思います。

スクリプトに2つのデータベース間のすべてのプロシージャを調べさせ、不一致を返すことで、2つ以上のデータベースを比較することは可能ですか?

効果のあるもの:

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

ボーナスとして、最新のスクリプトを古いスクリプトに適用することで、スクリプトにデータベースを自動的に同期させることは可能でしょうか?

どうもありがとう!

14
George Johnston

これを行うためのツールはたくさんあります。最高の1つは、Red-Gate SQLCompareです。もう1つの非常に優れた代替手段は、Visual Studio DatabaseProfessionalを使用してデータベーススキーマを管理することです。とりわけ、それは非常に素晴らしいスキーマ比較を行います。

19
Randy Minder

DBアーキテクト(Data Dude)用のSQLCompareまたはVisualStudioチームシステムがない場合...これを試してみてください... SQL2005以降

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)
11
SQLMenace

以下のスクリプトを使用して、どのプロシージャ(およびわずかに変更された他のオブジェクト)が異なるかを識別できます。

データベースを同期するには、 ApexSQL Diff を試してみてください。これは、RedGateのSQLCompareに似ています。

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' 
11
John Moore

RedGateのSQLCompareは完璧なソリューションです。ただし、そのコストを支払う余裕がない場合は、無料の非常に優れたソフトウェアがあります:StarInixのSQL比較 http:// www.starinix.com/sqlcompare02.htm

3
Gustavo Cardoso

これは接線方向に関連していますが、2つのストアドプロシージャのテキスト間のパーセンテージ一致統計を提供するものを作成しました: http://www.sqlservercentral.com/scripts/T-SQL/65787/

1
Jesse

両方のデータベースのすべてのストアドプロシージャと、他のデータベースに存在しないものの出力名を比較する場合は、以下を使用します。これはストアドプロシージャの定義だけをチェックするのではなく、その名前だけをチェックすることに注意してくださいが、それをチェックする方法もあります。

-- 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')
1
Boris

はい、RedGateのものは素晴らしいですが、それは2つの異なるデータベースのストアドプロシージャを比較するために私が行ったことです。1-すべてのストアドプロシージャを別々のファイルにスクリプト化しました。これは、Microsoft SQL Server ManagementStudioウィザードを使用して実行できます。 2-私が比較している他のデータベースからも同じことをしました。 3-無料のKDiff3を開始したと思います。 4-トロールする必要がある2つのディレクトリを指定しました。 5-赤で表示されている場所をダブルクリックして結果を確認すると、下のパネルに違いが表示されます。

完了しました。

1
Andrei Bazanov

単純な答えですが、すべての手順でスクリプトを削除して作成するのは非常に簡単で効果的です。

1
Brian Spencer

次のプロシージャは、2つの異なるデータベースの関数、プロシージャ、トリガーの違いを見つけることができます。データベース名をパラメーターとして渡します。

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
0
Seenivasan