SQL Serverは、1つまたは複数のデータベーステーブルを別のデータベース、または同じデータベースに異なる名前で複製またはアーカイブするためのさまざまなソリューションを提供します。 SQL Server開発者またはデータベース管理者は、これら2つのテーブルのデータが同一であることを確認する必要があり、誤ってこれら2つのテーブル間でデータが複製されない場合は、データを同期する必要がある状況に直面する可能性があります。テーブルの間。さらに、ソーステーブルと宛先テーブルのスキーマの違いが原因でデータの同期またはレプリケーションプロセスを中断するエラーメッセージを受け取った場合は、スキーマの違いを特定する簡単で迅速な方法を見つけ、テーブルを変更して作成する必要があります。スキーマは両側で同一であり、データ同期プロセスを再開します。
他の状況では、2つのテーブルのデータとスキーマが同一であるかどうかにかかわらず、YESまたはNOの答えを得る簡単な方法が必要です。この記事では、2つのテーブル間でデータとスキーマを比較するさまざまな方法について説明します。この記事で提供されているメソッドは、異なるデータベースでホストされているテーブルを比較します。これは、より複雑なシナリオであり、同じデータベースにある異なる名前のテーブルを比較するためにも簡単に使用できます。
テーブルのデータとスキーマを比較するために使用できるさまざまな方法とツールについて説明する前に、2つの新しいデータベースを作成し、各データベースに1つのテーブルを作成して、これら2つのテーブルの間に1つの小さなデータタイプの違いがあるデモ環境を準備します。以下のCREATEDATABASEおよびCREATETABLET-SQLステートメントに示されています。
CREATE DATABASE TESTDB CREATE DATABASE TESTDB2 CREATE TABLE TESTDB.dbo.FirstComTable ( ID INT IDENTITY (1,1) PRIMARY KEY, FirstName VARCHAR (50), LastName VARCHAR (50), Address VARCHAR (500) ) GO CREATE TABLE TESTDB2.dbo.FirstComTable ( ID INT IDENTITY (1,1) PRIMARY KEY, FirstName VARCHAR (50), LastName VARCHAR (50), Address NVARCHAR (400) ) GO
データベースとテーブルを作成したら、以下のINSERT INTO T-SQLステートメントに示すように、2つのテーブルに5つの同じ行を入力し、最初のテーブルにのみ別の新しいレコードを挿入します。
INSERT INTO TESTDB.dbo.FirstComTable VALUES ('AAA','BBB','CCC') GO 5 INSERT INTO TESTDB2.dbo.FirstComTable VALUES ('AAA','BBB','CCC') GO 5 INSERT INTO TESTDB.dbo.FirstComTable VALUES ('DDD','EEE','FFF') GO
これで、テスト環境でデータとスキーマの比較方法の説明を開始する準備が整いました。
LEFTJOINを使用してテーブルデータを比較する
LEFT JOIN T-SQLキーワードは、左側のテーブルからすべてのレコードを返し、右側のテーブルから一致したレコードのみを返し、2つのテーブル間に一致がない場合は右側のテーブルからNULL値を返すことにより、2つのテーブルからデータを取得するために使用されます。
データ比較の目的で、LEFT JOINキーワードを使用して、以下のSELECTステートメントのように、この場合はID列などの共通の一意の列に基づいて2つのテーブルを比較できます。
SELECT * FROM TESTDB.dbo.FirstComTable F LEFT JOIN TESTDB2.dbo.FirstComTable S ON F.ID =S.ID
前のクエリは、以下に示すように、結果の右側にNULL値を表示することにより、最初のテーブルに存在し、2番目のテーブルにはない行に加えて、2つのテーブルに存在する共通の5行を返します。
前の結果から、最初のテーブルに存在する6番目の列が2番目のテーブルから欠落していることを簡単に導き出すことができます。テーブル間で行を同期するには、新しいレコードを2番目のテーブルに手動で挿入する必要があります。 LEFT JOINメソッドは、新しい行の検証には役立ちますが、列の値を更新する場合には役立ちません。 5行目のアドレス列の値を変更すると、以下に明確に示すように、LEFTJOINメソッドはその変更を検出しません。
EXCEPT句を使用してテーブルデータを比較する
EXCEPTステートメントは、2番目のクエリ(右のクエリ)から返されない最初のクエリ(左のクエリ)からの行を返します。つまり、EXCEPTステートメントは2つのSELECTステートメントまたはテーブルの違いを返すため、これらのテーブルのデータを簡単に比較できます。
EXCEPTステートメントを使用して、以前に作成したテーブルのデータを比較できます。以下のT-SQLステートメントを使用して、最初のテーブルからのSELECT*クエリと2番目のテーブルからのSELECT*クエリの違いを取得します。
SELECT * FROM TESTDB.dbo.FirstComTable F EXCEPT SELECT * FROM TESTDB2.dbo. FirstComTable S
以下に示すように、前のクエリの結果は、最初のテーブルでは使用可能で、2番目のテーブルでは使用できない行になります。
EXCEPTステートメントを使用して2つのテーブルを比較することは、LEFT JOINステートメントよりも優れており、更新されたレコードがデータの差異の結果に取り込まれます。 2番目のテーブルの行番号5のアドレスを更新し、EXCEPTステートメントを使用して違いを再度確認したとすると、次のように行番号5が違いの結果とともに返されることがわかります。
EXCEPTステートメントを使用して2つのテーブルのデータを比較することの唯一の欠点は、2番目のテーブルの欠落しているレコードに対してINSERTステートメントを記述して、データを手動で同期する必要があることです。比較される2つのテーブルは、正しい結果を得るためのキー付きテーブルであり、比較に使用される一意のキーがあることを考慮してください。以下のステートメントのように、EXCEPTステートメントの両方の側でSELECTステートメントからID固有の列を削除し、残りの非キー列をリストすると、次のようになります。
SELECT FirstName, LastName, Address FROM TESTDB.dbo. FirstComTable F EXCEPT SELECT FirstName, LastName, Address FROM TESTDB2.dbo. FirstComTable S
結果には、以下の結果に示すように、新しいレコードのみが返され、更新されたレコードはリストされないことが示されます。
UNIONALL…GROUPBYを使用してテーブルデータを比較する
UNION ALLステートメントを使用して、一意のキー列に基づいて2つのテーブルのデータを比較することもできます。 UNION ALLステートメントを使用して2つのテーブルの差を返すには、以下のT-SQLクエリに示すように、SELECTステートメントで比較する列をリストし、これらの列をGROUPBY句で使用する必要があります。
SELECT DISTINCT * FROM ( SELECT * FROM ( SELECT * FROM TESTDB.dbo. FirstComTable UNION ALL SELECT * FROM TESTDB2.dbo. FirstComTable) Tbls GROUP BY ID,FirstName, LastName, Address HAVING COUNT(*)<2) Diff
そして、以下に示すように、最初のテーブルに存在し、2番目のテーブルから欠落している行のみが返されます。
前のクエリは、レコードを更新する場合にも正常に機能しますが、方法が異なります。以下に示す行番号5の場合のように、両方のテーブルから更新された列に加えて、新しく挿入されたレコードが返されます。
SQLServerデータツールを使用してテーブルデータを比較する
Microsoft VisualStudio上に構築されたSQLServerデータツール(SSDTとも呼ばれます)を使用すると、2つの異なるデータベースでホストされている一意のキー列に基づいて、同じ名前の2つのテーブルのデータを簡単に比較し、これらのテーブルのデータを同期できます。 、または後で使用する同期スクリプトを生成します。
開いたSSDTウィンドウから、[ツール]メニュー-> [SQL Server]リストをクリックし、[新しいデータの比較]を選択します。 以下に示すように、オプション:
表示された接続ウィンドウで、以前に接続したセッションから選択するか、[接続のプロパティ]ウィンドウにSQL Server名、資格情報、データベース名を入力して、[接続]をクリックします。 、以下に示すように:
表示された新しいデータ比較ウィザードで、ソースデータベースとターゲットデータベースの名前、およびテーブルの比較プロセスで使用される比較オプションを指定し、[次へ]をクリックします。 、以下に示すように:
次のウィンドウで、テーブルの名前を指定します。これは、ソースデータベースとターゲットデータベースで同じ名前である必要があり、両方のデータベースで比較され、[完了]をクリックします。 、以下のように:
表示される結果には、ソースで検出されてターゲットから欠落しているレコードの数、ターゲットで検出されてソースから欠落しているレコードの数、同じキーと異なる列の値を持つ更新されたレコードの数が表示されます(異なるレコード)最後に、以下に示すように、両方のテーブルで見つかった同一のレコードの数:
前の結果のテーブル名をクリックすると、以下に示すように、これらの調査結果の詳細が表示されます。
以下のように、同じツールを使用してスクリプトを生成し、ソーステーブルとターゲットテーブルを同期したり、不足している変更や異なる変更でターゲットテーブルを直接更新したりできます。
[スクリプトの生成]オプションをクリックすると、以下に示すように、ターゲットテーブルに列が欠落しているINSERTステートメントが表示されます。
BEGIN TRANSACTION
BEGIN TRANSACTION SET IDENTITY_INSERT [dbo].[FirstComTable] ON INSERT INTO [dbo].[FirstComTable] ([ID], [FirstName], [LastName], [Address]) VALUES (6, N'DDD', N'EEE', N'FFF') SET IDENTITY_INSERT [dbo].[FirstComTable] OFF COMMIT TRANSACTION
[ターゲットの更新]オプションを選択すると、以下のメッセージのように、最初に変更を実行するための確認を求められます。
同期後、以下に示すように、2つのテーブルのデータが同一になることがわかります。
「dbForgeStudioforSQLServer」サードパーティツールを使用してテーブルデータを比較する
SQL Serverの世界では、データベース管理者と開発者の作業を容易にするサードパーティツールを多数見つけることができます。データベース管理タスクを簡単にするこれらのツールの1つは、データベース管理および開発タスクを実行する簡単な方法を提供するdbForge Studio forSQLServerです。このツールは、データベーステーブルのデータを比較し、これらのテーブルを同期するのにも役立ちます。
[比較]メニューから、[新しいデータの比較]を選択します 以下に示すように、オプション:
新規データ比較ウィザードから、ソースデータベースとターゲットデータベースを指定し、[次へ]をクリックします :
利用可能なさまざまなマッピングおよび比較オプションから適切なオプションを選択し、[次へ]をクリックします :
データ比較プロセスに参加する1つまたは複数のテーブルの名前を指定します。ソースデータベーステーブルとターゲットデータベーステーブルの間にスキーマの違いがある場合、ウィザードは警告メッセージを表示します。 比較をクリックします 続行するには:
最終結果には、ソーステーブルとターゲットテーブルのデータの違いが詳細に表示され、クリックする機能が表示されます 次に示すように、ソーステーブルと宛先テーブルを同期します。
sys.columnsを使用してテーブルスキーマを比較する
この記事の冒頭で述べたように、テーブルを複製またはアーカイブするには、ソーステーブルとターゲットテーブルのスキーマが同一であることを確認する必要があります。 SQL Serverは、同じデータベースまたは異なるデータベース内のテーブルのスキーマを比較するためのさまざまな方法を提供します。最初のメソッドは、sys.columnsシステムカタログビューをクエリすることです。このビューは、各列のプロパティを使用して、列を持つオブジェクトの列ごとに1つの行を返します。
異なるデータベースにあるテーブルのスキーマを比較するには、別のデータベースでホストされているテーブルを提供することなく、現在のデータベースの下にあるテーブル名をsys.columnsに提供する必要があります。これを実現するために、sys.columnsを2回クエリし、各クエリの結果を一時テーブルに保存し、最後に、以下に明確に示すように、EXCEPTT-SQLコマンドを使用してこれら2つのクエリの結果を比較します。
USE TESTDB SELECT name, system_type_id, user_type_id,max_length, precision,scale, is_nullable, is_identity INTO #DBSchema FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.FirstComTable') GO USE TestDB2 GO SELECT name, system_type_id, user_type_id,max_length, precision,scale, is_nullable, is_identity INTO #DB2Schema FROM sys.columns WHERE object_id = OBJECT_ID(N'dbo.FirstComTable '); GO SELECT * FROM #DBSchema EXCEPT SELECT * FROM #DB2Schema
結果は、以下に示すように、アドレス列の定義がこれら2つのテーブルで異なり、正確な違いに関する特定の情報がないことを示しています。
INFORMATION_SCHEMA.COLUMNSを使用してテーブルスキーマを比較する
INFORMATION_SCHEMA.COLUMNSシステムビューを使用して、テーブル名を指定することにより、さまざまなテーブルのスキーマを比較することもできます。ここでも、異なるデータベースでホストされている2つのテーブルを比較するために、INFORMATION_SCHEMA.COLUMNSを2回クエリし、各クエリの結果を一時テーブルに保持し、最後に、次に示すように、EXCEPTT-SQLコマンドを使用してこれら2つのクエリの結果を比較します。明らかに下:
USE TestDB SELECT COLUMN_NAME, IS_NULLABLE,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION,NUMERIC_SCALE INTO #DBSchema FROM [INFORMATION_SCHEMA].[COLUMNS] SC1 WHERE SC1.TABLE_NAME='FirstComTable' GO USE TestDB2 SELECT COLUMN_NAME, IS_NULLABLE,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH, NUMERIC_PRECISION,NUMERIC_SCALE INTO #DB2Schema FROM [INFORMATION_SCHEMA].[COLUMNS] SC2 WHERE SC2.TABLE_NAME='FirstComTable' GO SELECT * FROM #DBSchema EXCEPT SELECT * FROM #DB2Schema
また、結果は前の結果と多少似ており、以下に示すように、アドレス列の定義がこれら2つのテーブルで異なり、正確な違いに関する具体的な情報がないことを示しています。
dm_exec_describe_first_result_setを使用してテーブルスキーマを比較する
テーブルスキーマは、Transact-SQLステートメントをパラメーターとして受け取り、ステートメントの最初の結果セットのメタデータを記述するdm_exec_describe_first_result_set動的管理関数をクエリすることによっても比較できます。
2つのテーブルのスキーマを比較するには、以下のT-SQLクエリのように、dm_exec_describe_first_result_set DMFをそれ自体と結合し、各テーブルからのSELECTステートメントをパラメーターとして提供する必要があります。
SELECT FT.name , ST.name , FT.system_type_name , ST.system_type_name , FT.max_length , ST.max_length , FT.precision , ST.precision , FT.scale , ST.scale , FT.is_nullable , ST.is_nullable , FT.is_identity_column , ST.is_identity_column FROM sys.dm_exec_describe_first_result_set (N'SELECT * FROM TestDB.DBO.FirstComTable', NULL, 0) FT LEFT OUTER JOIN sys.dm_exec_describe_first_result_set (N'SELECT * FROM TestDB2.DBO.FirstComTable', NULL, 0) ST ON FT.Name =ST.Name GO
今回は、以下に示すように、2つのテーブルの違い、つまり[アドレス]列のサイズとタイプを目で比較できるため、結果がより明確になります。
SQLServerデータツールを使用したテーブルスキーマの比較
SQL Serverデータツールを使用して、さまざまなデータベースにあるテーブルのスキーマを比較することもできます。 [ツール]メニューで、[新しいスキーマの比較]を選択します 以下に示すように、SQLServerオプションリストのオプション:
接続パラメータを入力したら、[比較]ボタンをクリックします。
比較結果は、具体的には、以下のスナップショットのように陰影を付けた、CREATETABLET-SQLコマンドの形をした2つのテーブル間のスキーマの違いを示しています。
簡単にクリックできます を使用してテーブルスキーマを同期するか、[ 以下に示すように、変更をスクリプト化して後で実行します。
dbForge Studio forSQLServerサードパーティツールを使用したテーブルスキーマの比較
dbForge Studio for SQL Serverツールは、さまざまなデータベーステーブルのスキーマを比較する機能を提供します。 [比較]メニューから、[新しいスキーマの比較]を選択します オプション、以下のように:
ソースデータベースとターゲットデータベースの両方の接続プロパティを指定した後、使用可能な選択肢から適切なマッピングオプションを選択し、[次へ]をクリックします。 :
オブジェクトを比較するスキーマを選択し、次へをクリックします :
スキーマ比較プロセスに参加する1つまたは複数のテーブルを指定し、[比較]をクリックします。 、以下のように、[オブジェクトフィルター]ウィンドウのデフォルト設定の変更をスキップする場合:
表示される比較結果は、以下に示すように、2つのテーブルを同期するために実行するアクションを指定する機能を使用して、2つの列間で異なるデータ型の部分を正確に強調表示することにより、2つのテーブルスキーマの違いを示します。 :
2つのテーブルのスキーマを同期するように調整する場合は、ボタンをクリックして、スキーマ同期ウィザードで、ターゲットテーブルに対して直接変更を実行するか、将来使用するスクリプトを作成するかを以下のように指定します。
便利なリンク:
- 演算子の設定– EXCEPTおよびINTERSECT(Transact-SQL)
- 演算子の設定– UNION(Transact-SQL)
- SQL Serverデータツール(SSDT)をダウンロードする
- 1つ以上のテーブルのデータを参照データベースのデータと比較して同期する
- sys.dm_exec_describe_first_result_set(Transact-SQL)
- sys.columns(Transact-SQL)
- システム情報スキーマビュー(Transact-SQL)
便利なツール:
dbForge Schema Compare for SQL Server –SQLServer上のデータベースを比較および同期する際の時間と労力を節約する信頼性の高いツール。
dbForge Data Compare for SQL Server –ビッグデータを処理できる強力なSQL比較ツール。