次の方法で共有


チュートリアル : 2 つのデータベースのスキーマを比較する

このトピックの内容は、次の製品に該当します。

Visual Studio Ultimate

Visual Studio Premium

Visual Studio Professional 

Visual Studio Express

トピック該当 トピック該当 トピック該当なし トピック該当なし

このチュートリアルでは、Visual Studio を使って 2 つのデータベースのスキーマを比較します。 スキーマ比較操作を行うと、スキーマの相違点からデータ定義言語 (DDL: Data Definition Language) スクリプトも生成されます。 このファイルを使用して、ターゲットのスキーマをソースのスキーマと同期します。 詳細については、「データベース スキーマの比較と同期」を参照してください。

このチュートリアルでは、次の手順を行います。

  • 簡単なデータベース プロジェクトの作成。 「チュートリアル: データベースとデータベース プロジェクトのスキーマの比較」の作業を実行済みの場合は、その結果のデータベースを使用して、この手順をスキップできます。

  • 空のデータベースの作成。 CompareProjectDB データベースをソースとして使用し、ターゲットとして使用する空のデータベースを作成します。

  • 2 つのデータベースのスキーマの比較。 スキーマを比較して、2 つのデータベースの構造上の相違点を見つけ、この相違点を表に示し、相違点を表す DDL スクリプトを生成します。

  • 同期スクリプトの確認と実行。 DDL スクリプトを確認し、実行前にこのスクリプトを編集できます。

  • ターゲット データベースの更新。 DDL スクリプトを実行して、ターゲットのスキーマを変更します。

必須コンポーネント

次の製品をインストールしている必要があります。

  • SQL Server 2008

  • ターゲット データベース サーバーのデータベースを作成および更新するアクセス許可

  • Visual Studio Premium または Visual Studio Ultimate

簡単なデータベースの作成

次のタスクを実行して、簡単なデータベースを作成します。

  • データベース スキーマを含むスクリプトの作成

  • データベース プロジェクトの作成とそのスキーマのインポート

  • データベース プロジェクトの分離開発環境への配置

データベース スキーマを含むスクリプトの作成

スキーマのインポートに使用するスクリプトを作成するには

  1. [ファイル] メニューの [新規作成] をポイントし、[ファイル] をクリックします。

    [新しいファイル] ダイアログ ボックスが表示されます。

  2. [カテゴリ] ボックスの一覧で、[全般] がまだ強調表示されていない場合は、クリックします。

  3. [テンプレート] ボックスの一覧の [SQL ファイル] をクリックし、[開く] をクリックします。

    Transact-SQL エディターが表示されます。

  4. 次の Transact-SQL コードをコピーし、Transact-SQL エディターに貼り付けます。

    PRINT N'Creating Sales...';
    GO
    CREATE SCHEMA [Sales]
        AUTHORIZATION [dbo];
    GO
    PRINT N'Creating Sales.Customer...';
    GO
    CREATE TABLE [Sales].[Customer] (
        [CustomerID]   INT IDENTITY (1, 1) NOT NULL,
        [CustomerName] NVARCHAR (40) NOT NULL,
        [YTDOrders] INT NOT NULL,
        [YTDSales] INT NOT NULL
    );
    GO
    PRINT N'Creating Sales.Orders...';
    GO
    CREATE TABLE [Sales].[Orders] (
        [CustomerID] INT NOT NULL,
        [OrderID] INT IDENTITY (1, 1) NOT NULL,
        [OrderDate] DATETIME NOT NULL,
        [FilledDate] DATETIME NULL,
        [Status] CHAR (1) NOT NULL,
        [Amount] INT NOT NULL
    );
    GO
    PRINT N'Creating Sales.Def_Customer_YTDOrders...';
    GO
    ALTER TABLE [Sales].[Customer]
        ADD CONSTRAINT [Def_Customer_YTDOrders] DEFAULT 0 FOR [YTDOrders];
    GO
    PRINT N'Creating Sales.Def_Customer_YTDSales...';
    GO
    ALTER TABLE [Sales].[Customer]
        ADD CONSTRAINT [Def_Customer_YTDSales] DEFAULT 0 FOR [YTDSales];
    GO
    PRINT N'Creating Sales.Def_Orders_OrderDate...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [Def_Orders_OrderDate] DEFAULT GetDate() FOR [OrderDate];
    GO
    PRINT N'Creating Sales.Def_Orders_Status...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [Def_Orders_Status] DEFAULT 'O' FOR [Status];
    GO
    PRINT N'Creating Sales.PK_Customer_CustID...';
    GO
    ALTER TABLE [Sales].[Customer]
        ADD CONSTRAINT [PK_Customer_CustID] PRIMARY KEY CLUSTERED ([CustomerID] ASC) WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF);
    GO
    PRINT N'Creating Sales.PK_Orders_OrderID...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [PK_Orders_OrderID] PRIMARY KEY CLUSTERED ([OrderID] ASC) WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF);
    GO
    PRINT N'Creating Sales.FK_Orders_Customer_CustID...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [FK_Orders_Customer_CustID] FOREIGN KEY ([CustomerID]) REFERENCES [Sales].[Customer] ([CustomerID]) ON DELETE NO ACTION ON UPDATE NO ACTION;
    GO
    PRINT N'Creating Sales.CK_Orders_FilledDate...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [CK_Orders_FilledDate] CHECK ((FilledDate >= OrderDate) AND (FilledDate < '01/01/2010'));
    GO
    PRINT N'Creating Sales.CK_Orders_OrderDate...';
    GO
    ALTER TABLE [Sales].[Orders]
        ADD CONSTRAINT [CK_Orders_OrderDate] CHECK ((OrderDate > '01/01/2005') and (OrderDate < '01/01/2020'));
    GO
    PRINT N'Creating Sales.uspCancelOrder...';
    GO
    CREATE PROCEDURE [Sales].[uspCancelOrder]
    @OrderID INT
    AS
    BEGIN
    DECLARE @Delta INT, @CustomerID INT
    BEGIN TRANSACTION
        SELECT @Delta = [Amount], @CustomerID = [CustomerID]
         FROM [Sales].[Orders] WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Orders]
       SET [Status] = 'X'
    WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Customer]
       SET
       YTDOrders = YTDOrders - @Delta
        WHERE [CustomerID] = @CustomerID
    COMMIT TRANSACTION
    END
    GO
    PRINT N'Creating Sales.uspFillOrder...';
    GO
    CREATE PROCEDURE [Sales].[uspFillOrder]
    @OrderID INT, @FilledDate DATETIME
    AS
    BEGIN
    DECLARE @Delta INT, @CustomerID INT
    BEGIN TRANSACTION
        SELECT @Delta = [Amount], @CustomerID = [CustomerID]
         FROM [Sales].[Orders] WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Orders]
       SET [Status] = 'F',
           [FilledDate] = @FilledDate
    WHERE [OrderID] = @OrderID;
    
    UPDATE [Sales].[Customer]
       SET
       YTDSales = YTDSales - @Delta
        WHERE [CustomerID] = @CustomerID
    COMMIT TRANSACTION
    END
    GO
    PRINT N'Creating Sales.uspNewCustomer...';
    GO
    CREATE PROCEDURE [Sales].[uspNewCustomer]
    @CustomerName NVARCHAR (40)
    AS
    BEGIN
    INSERT INTO [Sales].[Customer] (CustomerName) VALUES (@CustomerName);
    SELECT SCOPE_IDENTITY()
    END
    GO
    PRINT N'Creating Sales.uspPlaceNewOrder...';
    GO
    CREATE PROCEDURE [Sales].[uspPlaceNewOrder]
    @CustomerID INT, @Amount INT, @OrderDate DATETIME, @Status CHAR (1)='O'
    AS
    BEGIN
    DECLARE @RC INT
    BEGIN TRANSACTION
    INSERT INTO [Sales].[Orders] (CustomerID, OrderDate, FilledDate, Status, Amount) 
         VALUES (@CustomerID, @OrderDate, NULL, @Status, @Amount)
    SELECT @RC = SCOPE_IDENTITY();
    UPDATE [Sales].[Customer]
       SET
       YTDOrders = YTDOrders + @Amount
        WHERE [CustomerID] = @CustomerID
    COMMIT TRANSACTION
    RETURN @RC
    END
    GO
    
  5. [ファイル] メニューの [名前を付けて SqlQuery_1.sql を保存] をクリックします。

    [名前を付けてファイルを保存] ダイアログ ボックスが表示されます。

  6. [オブジェクト名] に「SampleImportScript.sql」と入力します。

    ファイルはコンピューター上の任意の場所に保存できます。 場所のメモを作成し、このスクリプトを次のプロシージャで使用できるようにします。

  7. [保存] をクリックします。

  8. [ファイル] メニューの [ソリューションを閉じる] をクリックします。

    次に、データベース プロジェクトを作成し、作成したスクリプトからスキーマをインポートします。

データベース プロジェクトの作成とそのスキーマのインポート

データベース プロジェクトを作成するには

  1. [ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。

    [新しいプロジェクト] ダイアログ ボックスが表示されます。

  2. [インストールされたテンプレート] で、[データベース] ノードを展開し、[SQL Server] をクリックします。

  3. テンプレートの一覧の [SQL Server 2008 データベース プロジェクト] をクリックします。

  4. [名前] に「CompareProjectDB」と入力します。

  5. [ソリューション] の一覧で、[ソリューションの作成] が強調表示されていない場合は、クリックします。

  6. [ソリューションのディレクトリを作成] チェック ボックスがまだオンになっていない場合はオンにします。

  7. [ソース管理に追加] チェック ボックスがまだオフになっていない場合はオフにし、[OK] をクリックします。

    データベース プロジェクトが作成され、ソリューション エクスプローラーに表示されます。 次に、スクリプトからデータベース スキーマをインポートします。

スクリプトからデータベース スキーマをインポートするには

  1. [プロジェクト] メニューの [スクリプトのインポート] をクリックします。

  2. [ようこそ] ページを読んでから、[次へ] をクリックします。

  3. [参照] をクリックし、SampleImportScript.sql ファイルを保存した場所のパスを指定します。

  4. [SampleImportScript.sql] ファイルをダブルクリックし、[完了] をクリックします。

    指定したスクリプトがインポートされ、このスクリプトで定義したオブジェクトがデータベース プロジェクトに追加されます。

  5. 概要を確認し、[完了] をクリックして操作を完了します。

    注意

    Sales.uspFillOrder プロシージャには意図的なコーディング エラーがあります。このエラーは単体テストのチュートリアルで見つけて修正します。

作成されたプロジェクトを確認するには

  1. ソリューション エクスプローラーで、[スキーマ オブジェクト] 子ノードを展開します。

  2. 階層内で [スキーマ オブジェクト] ノードの下にある下位ノードを調べます。

    ソリューション エクスプローラーには、データベース オブジェクトを定義するファイルがあります。

  3. [表示] メニューの [スキーマ ビュー] をクリックします。

  4. スキーマ ビューで、[CompareProjectDB] ノードを展開します。

  5. 階層内で [CompareProjectDB] ノードの下にある下位ノードを調べます。

    スキーマ ビューには、ソリューション エクスプローラーに表示されるファイルで定義されているオブジェクトが表示されます。

分離開発環境の配置

次に、インポートしたスキーマがあってデータはないデータベースを作成するため、プロジェクトを配置します。 このデータベースは、分離開発環境またはサンドボックスに作成します。 そのため、他の作業による干渉を受けずにデータベースを開発およびテストできます。

データベース プロジェクトを構成およびビルドするには

  1. ソリューション エクスプローラーで、[CompareProjectDB] データベース プロジェクトをクリックします。

  2. [プロジェクト] メニューの [CompareProjectDB のプロパティ] をクリックします。

    プロジェクトのプロパティ ダイアログ ボックスが表示されます。

  3. [配置] タブをクリックします。

  4. [配置設定の構成] ボックスの一覧の [マイ分離開発環境] をクリックします。 分離開発環境用の設定を構成することで、テスト サーバーまたは運用サーバーなどの他の環境で使用する設定とは異なる配置設定を使用できます。

  5. [配置動作] ボックスの一覧の [配置スクリプト (.sql) を作成してデータベースに配置します] をクリックします。

  6. [ターゲット データベースの設定][編集] をクリックします。

    [接続のプロパティ] ダイアログ ボックスが表示されます。

  7. 作成するデータベースの接続プロパティを設定し、[OK] をクリックします。

    [ターゲット接続] ボックスに正しい接続文字列が表示されます。

    ヒント

    データベースは、テスト サーバー、開発サーバー、またはローカル コンピューターに作成する必要があります。 運用サーバーは指定しないでください。

  8. [ターゲット データベース名] に「CompareProjectDB」と入力します。

  9. [配置構成ファイル] の横の [編集] をクリックします。

  10. [データ損失が発生する場合に増分配置をブロック] チェック ボックスをオフにします。

    注意

    このチュートリアルでは、データベース単体テストの一部として配置した空のデータベースに対して、ストアド プロシージャをテストします。 分離開発環境でストアド プロシージャをテストするため、既存のデータを保持しておく必要はありません。

  11. [ファイル] メニューの [すべてを保存] をクリックします。

  12. [ビルド] メニューの [ソリューションのビルド] をクリックします。

    先ほど設定したプロパティに基づいて、配置スクリプトのビルド方法が決まります。 ビルドの状態が [出力] ウィンドウに表示され、最後の行に "ビルド: 1 正常終了または最新の状態" と表示されます。

データベース プロジェクトを配置するには

  1. ソリューション エクスプローラーで、[CompareProjectDB] データベース プロジェクトをクリックします。

  2. [ビルド] メニューの [CompareProjectDB の配置] をクリックします。

    ヒント

    この配置は、テスト サーバー、開発サーバー、またはローカル コンピューターに対して実行する必要があります。 運用サーバーは指定しないでください。

    データベース プロジェクトが新しいデータベースに配置されます。 配置の状態が [出力] ウィンドウに表示され、最後の行に "配置成功" と表示されます。 次に、この配置したデータベースとの比較に使用する空のデータベースを作成します。

空のデータベースの作成

空のデータベースを作成するには

  1. [ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。

    [新しいプロジェクト] ダイアログ ボックスが表示されます。

  2. [インストールされたテンプレート] のリストで [データベース] ノードを展開し、[SQL Server] をクリックします。

  3. [SQL Server 2008 ウィザード] をクリックします。

  4. [名前] に「EmptyDB」と入力します。

  5. その他のフィールドについては既定値をそのまま使用し、[OK] をクリックします。

  6. 新規データベース プロジェクト ウィザードで、[ビルド/配置の構成] をクリックします。

  7. [配置動作] ボックスの一覧の [配置スクリプト (.sql) を作成してデータベースに配置します] をクリックします。

  8. [ターゲット接続][参照] をクリックします。

  9. 空のデータベースを作成するデータベース サーバーへの接続を指定し、[完了] をクリックします。

    EmptyDB というデータベース プロジェクトが作成され、ソリューション エクスプローラーに表示されます。

  10. ソリューション エクスプローラーで、[EmptyDB] データベース プロジェクトをクリックします。

  11. [ビルド] メニューの [EmptyDB の配置] をクリックします。

    データベース プロジェクトがビルドされ、指定したサーバーに配置されます。

2 つのデータベースのスキーマを比較する

2 つのデータベースのスキーマを比較するには

  1. [データ] メニューの [スキーマ比較] をポイントし、[新しいスキーマ比較] をクリックします。

    ソースとターゲットを指定できる [新しいスキーマ比較] ダイアログ ボックスが表示されます。 このダイアログ ボックスでは、ソースとターゲットが格納されているサーバーの名前、各データベースの名前、および各データベースに接続するときに使用する認証の種類を指定します。

    バックグラウンドで [スキーマ比較] ウィンドウが開き、SchemaCompare1 などの名前が Visual Studio によって自動的に割り当てられます。

  2. [ソース スキーマ] の下の [データベース] をクリックし、CompareProjectDB データベースに対応する接続をクリックします。

    接続が一覧に表示されない場合は、[新しい接続] をクリックします。 [接続のプロパティ] ダイアログ ボックスで、CompareProjectDB データベースがあるサーバー、接続するときに使用する認証の種類、およびデータベース事態を指定します。 終了したら、[OK] をクリックします。

    注意

    接続が確立されると、サーバー エクスプローラー[データ接続] の下にその接続が表示されます。

  3. [ターゲット スキーマ] で、[データベース] をクリックし、EmptyDB データベースに対応する接続をクリックします。

    接続が一覧に表示されない場合は、[新しい接続] をクリックします。 [接続のプロパティ] ダイアログ ボックスで、EmptyDB データベースがあるサーバー、データベースに接続するときに使用する認証の種類、およびデータベース自体を指定します。 終了したら、[OK] をクリックします。

  4. [オプション] をクリックし、比較するオブジェクト、無視する相違点の種類、および生成する更新スクリプトに含める内容を指定します。

    注意

    データベースを比較するときは、SQLCMD 変数を指定しません。

  5. [全般] タブで、[比較オプション] ノードを展開します。

  6. [ファイルおよびログ ファイルの名前とパスを無視する] を選択します。

  7. [OK] をクリックします。

  8. [OK] をクリックします。

    スキーマ比較が開始されます。

    注意

    実行中の比較を停止するには、[データ] メニューの [スキーマ比較] をポイントし、[スキーマ比較の停止] をクリックします。

    どのような違いを相違点と見なすか、および更新スクリプトの作成方法を変更するオプションを設定できます。 詳細については、「方法 : データベース スキーマの比較に関するオプションを設定する」を参照してください。

    比較が終わると、2 つのデータベース間の構造上の相違点が [スキーマの比較] ウィンドウの表に表示されます。 この表の各行には、どちらか一方のデータベースにのみ存在するデータベース オブジェクトが 1 つ表示されます。 データベース オブジェクトは、種類別 (テーブル、ビュー、ストアド プロシージャ、ロールなど) にまとめられます。

ターゲット データベースの更新

ターゲットのスキーマを更新する場合は、2 つの選択肢があります。 [スキーマ比較] ウィンドウからスキーマを直接更新する方法と、Transact-SQL エディターを使用する方法です。 このセクションでは、この 2 つの選択肢について説明します。

スキーマ比較を実行すると、構造上の相違点が [スキーマの比較] ウィンドウの表に表示されます。 [CompareProjectDB (ソース データベース)] 列の各オブジェクトについて、そのオブジェクトを 2 つのデータベースで同期するために必要なアクションが [更新アクション] 列に表示されます。 この例の場合、ターゲットには既定のオブジェクトしか格納されていないので、[状態] 列の大部分は新規状態で、[更新アクション] 列の大部分は作成アクションです。

ターゲットへの更新の書き込み

[スキーマ比較] ウィンドウに示された更新アクションを使って、ターゲットのスキーマを更新できます。 このタスクを実行するには、「ターゲット データベースへの更新の書き込み」の手順に従います。

スクリプトの表示とターゲットへの更新の書き込み

更新スクリプトをエクスポートして確認し、必要に応じて変更した後で、これを使ってターゲット データベースを同期します。 このタスクを実行するには、「同期スクリプトの確認と実行」の手順に従います。

ターゲット データベースへの更新の書き込み

注意

運用サーバーまたは開発サーバーに更新を書き込む前に、ターゲット データベースのバックアップを考慮する必要があります。 一部のスキーマ変更は単一のトランザクション内で処理できないため、更新操作を開始して取り消した場合は、データが失われることがあります。 たとえば、ターゲット データベースのあるテーブルが、再作成時の準備中に削除されている場合があります。 その時点で更新を取り消すと、そのテーブルが失われることがあります。 このチュートリアルでは、空の開発データベースを更新します。 そのため、ターゲット データベースはバックアップしません。

ターゲット データベースに更新を書き込むには

  1. 比較結果の一覧で、[SQL ファイル] ノードまでスクロールします。

  2. CompareProjectDB ファイルと CompareProjectDB_Log ファイルについては、更新アクションを [作成] から [スキップ] に変更します。

    注意

    同じデータベース サーバー上にある 2 つのデータベースを比較する場合、ターゲットのデータとログ ファイルは既に存在し、ソース データベースによって使用中なので失敗します。 このチュートリアルでは、ファイルに対する更新をスキップし、データベースの内容を同期します。

  3. EmptyDB ファイルと EmptyDB_log ファイルについては、更新アクションを [ドロップ] から [スキップ] に変更します。

    注意

    ソース データベースからファイルを作成しないため、ターゲット データベースのファイルは削除しないでください。 このチュートリアルでは、ファイルに対する更新をスキップし、データベースの内容を同期します。

  4. [スキーマ比較] ツール バーの [更新の書き込み] をクリックします。

    [スキーマ比較] ウィンドウに示された更新アクションが実行されます。 この同期により、ソースのスキーマに一致するようにターゲットのスキーマが変更されます。

    注意

    更新アクションの実行中に操作を取り消すには、[データ] メニューの [スキーマ比較] をポイントし、[ターゲットへの書き込み] をクリックします。

    選択した更新が適用されたことを確認するためにもう一度比較を実行する場合は、[スキーマ比較] ツール バーの [最新の情報に更新] をクリックします。

同期スクリプトの確認と実行

同期スクリプトを確認するには

  1. [データ] メニューの [スキーマ比較] をポイントします。次に、[エクスポート先] をポイントし、[エディター] をクリックします。

    また、[スキーマ比較] ツール バーの [エディターにエクスポート] をクリックすることもできます。

    Transact-SQL エディターがオフライン モードで開き、Transact-SQL 同期スクリプトが表示されます。 このウィンドウには、Server.CompareProjectDB - SchemaUpdate_EmptyDB_1.sql といった名前が付いています。 また、Transact-SQL スクリプトが表示されます。 読み取りおよび書き込みアクセス権を持っているので、このウィンドウでスクリプトを変更できます。 変更した場合は、[ファイル] メニューの [上書き保存] をクリックします。 ファイルを保存するときは、パスと名前を指定できます。

  2. Transact-SQL エディターのツール バーで、[SQLCMD モード] をクリックします。

    SQLCMD モードを有効にしていない場合、スクリプトを実行しようとしたときにエラーが表示されます。

  3. 2 つのデータベースのスキーマを同期するために、このスクリプトを実行します。スクリプトを実行するには、Transact-SQL エディター ツール バーの [SQL の実行] をクリックするか、F5 キーを押します。

    [データベースへの接続] ダイアログ ボックスが表示されます。

  4. 空の EmptyDB データベースに対応する接続をクリックし、[OK] をクリックします。

    ヒント

    異なるデータベースに対して更新スクリプトを実行しようとすると、意図しない結果が発生することがあります。

    比較は、自動的には最新の状態に更新されません。 選択した更新が適用されたことを確認するためにもう一度比較を実行する場合は、[スキーマ比較] ツール バーの [最新の情報に更新] をクリックする必要があります。

次の手順

これで、2 つのデータベースのデータを比較できます。 詳細については、「方法: 2 つのデータベースのデータを比較して同期させる」を参照してください。

参照

処理手順

方法: 2 つのデータベースのデータを比較して同期させる

方法: データベース スキーマを比較する

チュートリアル: 2 つのデータベースのデータの比較

チュートリアル: データベースとデータベース プロジェクトのスキーマの比較

概念

1 つ以上のテーブルのデータを参照データベースのデータと比較して同期する

Visual Studio でのデータベースおよびデータ層アプリケーションの作成と管理