チュートリアル: データベースとデータベース プロジェクトのスキーマの比較
このトピックの内容は、次の製品に該当します。
Visual Studio Ultimate |
Visual Studio Premium |
Visual Studio Professional |
Visual Studio Express |
---|---|---|---|
このチュートリアルでは、Visual Studio を使用して、データベース プロジェクトのスキーマとデータベースのスキーマを比較します。チームがデータベース プロジェクトとデータベースを使用している方法に応じて、スキーマの変更をいずれかにコピーできます。 データベース開発のライフ サイクルが進行すると、次のような一般的なシナリオが経験することがあります。
プロジェクトがソースで、データベースがターゲットの場合。 データベース プロジェクトを使用すると、データベースを開発または保守できます。 プロジェクトのスキーマを変更した後に、ステージング サーバーでホストされるデータベースにコピーします。 後で、チームがデータベースを運用サーバーに配置することもできます。
このチュートリアルで実行する比較により、スキーマの相違点からデータ定義言語 (DDL: Data Definition Language) スクリプトが生成されます。 このスクリプトを使用すると、データベース プロジェクトのすべてまたは一部をデータベースに適用できます。 詳細については、「プロジェクトからデータベースに変更を反映する」を参照してください。
データベースがソースで、プロジェクトがターゲットの場合。 運用データベースのスキーマでエラーが見つかるか、スキーマが古くなり更新が必要になる可能性があります。 この探索により、データベースに緊急の更新を適用する必要が出てくる可能性があります。 プロジェクトをデータベースと同期しておくには、更新をデータベース プロジェクトにインポートします。 詳細については、「方法 : 更新をデータベースからデータベース プロジェクトにインポートする」を参照してください。
このチュートリアルでは、次の作業について説明します。
設定フェーズ
データベース プロジェクトを作成する。 新しいプロジェクトを空で開始します。
スクリプトからデータベース スキーマをインポートする。
データベース プロジェクトを構成および構築し、データベース サーバーに配置する。 データベースとプロジェクトのスキーマが同じになります。
実行フェーズ
データベース プロジェクトにテーブルを追加する。 InternationalShippers という 3 列のテーブルを追加します。
2 つのスキーマを比較する。 この比較では、データベース プロジェクトをソース、データベースをターゲットとして指定します。 そのため、結果にはデータベース プロジェクトの新しいテーブルとして InternationalShippers テーブルが表示されます。
プロジェクトからデータベースに変更を反映する。 データベース プロジェクトの新しい InternationalShippers テーブルを、配置済みのデータベースに反映できます。 この手順を実行すると、サンプル データベースの一部が上書きされます。
注意
また、データベースからデータベース プロジェクトに変更を反映することもできます。 詳細については、「方法 : 更新をデータベースからデータベース プロジェクトにインポートする」を参照してください。
必須コンポーネント
このチュートリアルを完了するには、次のアプリケーションとアクセス許可が必要です。
SQL Server 2008
ターゲット データベース サーバーのデータベースを作成および更新するアクセス許可
Visual Studio Premium または Visual Studio Ultimate
設定フェーズ
データベース プロジェクトを作成する
データベース プロジェクトを作成するには
[ファイル] メニューの [新規作成] をポイントし、[プロジェクト] をクリックします。
[新しいプロジェクト] ダイアログ ボックスが表示されます。
[インストールされたテンプレート] で、[データベース] ノードを展開し、[SQL Server] ノードを展開します。
テンプレートの一覧の [SQL Server 2008 データベース プロジェクト] をクリックします。
[名前] に「CompareProject」と入力し、[OK] をクリックします。
空の CompareProject が開き、ソリューション エクスプローラーに表示されます。
スクリプトからデータベース スキーマをインポートする
スキーマのインポートに使用するスクリプトを作成するには
[ファイル] メニューの [新規作成] をポイントし、[ファイル] をクリックします。
[新しいファイル] ダイアログ ボックスが表示されます。
[カテゴリ] ボックスの一覧で、[全般] がまだ強調表示されていない場合は、クリックします。
[テンプレート] ボックスの一覧の [SQL ファイル] をクリックし、[開く] をクリックします。
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
[ファイル] メニューの [名前を付けて SqlQuery_1.sql を保存] をクリックします。
[名前を付けてファイルを保存] ダイアログ ボックスが表示されます。
[オブジェクト名] に「SampleImportScript.sql」と入力します。
ファイルはコンピューター上の任意の場所に保存できます。 次の手順で使用する必要があるので、場所をメモします。
[保存] をクリックします。
[ファイル] メニューの [ソリューションを閉じる] をクリックします。
次に、データベース プロジェクトを作成し、作成したスクリプトからスキーマをインポートします。
スクリプトからデータベース スキーマをインポートするには
[プロジェクト] メニューの [データベース スクリプトのインポート] をクリックします。
[ようこそ] ページを読んでから、[次へ] をクリックします。
[参照] をクリックし、SampleImportScript.sql ファイルを保存した場所を参照します。
[SampleImportScript.sql] ファイルをダブルクリックし、[完了] をクリックします。
指定したスクリプトがインポートされ、このスクリプトで定義したオブジェクトがデータベース プロジェクトに追加されます。
結果の概要を確認し、[完了] をクリックします。
データベース プロジェクトの構成、ビルド、および配置
以下の手順では、分離開発環境 (サンドボックス) にインポートしたスキーマがあるデータベースを作成します。この環境で、データベースの開発とテストを行うことができます。
データベース プロジェクトを構成およびビルドするには
ソリューション エクスプローラーで CompareProject プロジェクトをクリックします。
[プロジェクト] メニューの [CompareProject のプロパティ] をクリックします。
CompareProject プロジェクトのプロパティが表示されます。
[配置] タブをクリックします。
[配置動作] ボックスの一覧の [配置スクリプト (.sql) を作成してデータベースに配置します] をクリックします。
[ターゲット データベースの設定] の [編集] をクリックします。
[接続のプロパティ] ダイアログ ボックスで、作業するデータベースの接続プロパティを設定し、[OK] をクリックします。
[ターゲット接続] ボックスに正しい接続文字列が表示されます。
ヒント
データベースは、テスト サーバー、開発サーバー、またはローカル コンピューターに作成する必要があります。 運用サーバーは使用しないでください。
[ターゲット データベース名] ボックスに「CompareProjectDB」と入力します。
[ファイル] メニューの [すべてを保存] をクリックします。
[ビルド] メニューの [ソリューションのビルド] をクリックします。
先ほど設定したプロジェクト プロパティに基づいて、配置スクリプトがビルドされます。 ビルドの状態が出力ウィンドウに表示され、最後の行に "ビルド: 1 正常終了または最新の状態" と表示されます。
データベース プロジェクトを配置するには
ソリューション エクスプローラーで CompareProject プロジェクトをクリックします。
[ビルド] メニューの [CompareProject の配置] をクリックします。
代替手段として、ソリューション エクスプローラーでプロジェクトを右クリックし、[配置] をクリックすることもできます。
ヒント
この配置は、テスト サーバー、開発サーバー、またはローカル コンピューターに対して実行する必要があります。 運用サーバーは使用しないでください。
データベース プロジェクトが新しいデータベースに配置されます。 配置の状態が [出力] ウィンドウに表示され、最後の行に "配置成功" と表示されます。
実行フェーズ
データベース プロジェクトにテーブルを追加する
プロジェクトにテーブルを追加するには
[表示] メニューの [スキーマ ビュー] をクリックします。
[スキーマ ビュー] が開き、CompareProject プロジェクトのスキーマが表示されます。
スキーマ ビューで、[CompareProject] ノード、[スキーマ] ノードの順に展開します。
[Sales] を右クリックし、[追加] をポイントして、[テーブル] をクリックします。
[新しい項目の追加 - CompareProject] ダイアログ ボックスが開きます。
[テンプレート] の [テーブル] をクリックします。
[名前] に「InternationalShippers」と入力し、[追加] をクリックします。
InternationalShippers という名前のテーブルが CompareProject プロジェクトに追加されます。 Transact-SQL エディターにテーブル定義が表示されます。
InternationalShippers.table.sql の SQL スクリプトを次のステートメントに変更します。
CREATE TABLE [Sales].[InternationalShippers] ( [ShipperID] [int] NOT NULL IDENTITY(1,1), [CompanyName] [nvarchar] (40) NOT NULL, [Region] [nvarchar] (40) NOT NULL, [Phone] [nvarchar] (24) NULL ) ON [PRIMARY]
[InternationalShippers.table.sql を保存] をクリックします。
スキーマ ビューで [InternationalShippers] テーブルを右クリックし、[ファイルをソリューション エクスプローラーで表示] をクリックします。
InternationalShippers.sql ファイルがソリューション エクスプローラーで強調表示されます。
F4 キーを押します。
[プロパティ] ウィンドウが表示され、InternationalShippers.table.sql ファイルのプロパティが表示されます。 Build Action プロパティを [ビルド] に設定し、このファイルがデータベース オブジェクトの定義を含んでいて解析および検証の必要があることを示します。
2 つのスキーマを比較する
2 つのスキーマを比較するには
[データ] メニューの [スキーマ比較] をポイントし、[新しいスキーマ比較] をクリックします。
[新しいスキーマ比較] ダイアログ ボックスが開きます。
[ターゲット スキーマ] で、[データベース] をクリックし、このチュートリアルで以前に配置したデータベースへの接続を指定し、[OK] をクリックします。
データベースのスキーマが、変更されたプロジェクトのスキーマと比較され、結果が [スキーマの比較] ウィンドウに表示されます。 CompareProject 列に、[Sales].[InternationalShippers] テーブルが表示されます。 テーブルのステータスは [新規]、更新アクションは [作成] です。 ここで変更を反映すると、ターゲット データベースでテーブルが作成されます。 詳細については、次の手順を参照してください。
目的の相違を確認および無視するには
比較結果の一覧で、[SQL ファイル] ノードまでスクロールします。
ターゲット データベースには、ステータスが [見つかりません] の 2 行が一覧に表示されます。ファイル グループのファイルの行とログ ファイルの行です。
各行の [更新アクション] をクリックし、アクションを [スキップ] に変更します。
データベース スキーマを更新するときに、ターゲット データベースに関連付けられたファイル グループのファイルやログ ファイルを変更しないこともよくあります。 アクションを [スキップ] に変更することで、ターゲット データベースは今後も現在のファイルを使用します。
次に、必要に応じて、ソース データベースと一致するようにターゲット データベースを更新できます。
プロジェクトからデータベースに変更を反映する
変更をターゲット データベースに反映するには
[スキーマ比較] ウィンドウで [更新の書き込み] をクリックします。
注意
プロジェクトに 1 つまたは複数のエラーがある場合、[更新の書き込み] ボタンが無効になることがあります。 この場合、[スキーマ比較] ステータス バーにメッセージが表示されます。
InternationalShippers テーブルの [作成] のアクションを含む、[スキーマ比較] ウィンドウに表示されたアクションが実行されます。 この同期により、データベース プロジェクトのスキーマに一致するようにデータベースのスキーマが変更されます。 更新操作が完了すると、スキーマが改めて比較され、結果が更新されます。
ターゲット スキーマの更新中に操作を取り消すには、[データ] メニューの [スキーマ比較] をポイントし、[ターゲットへの書き込み] をクリックします。
ヒント
一部のスキーマ変更はトランザクションのスコープ内で処理できないため、更新操作を取り消した場合は、データが失われることがあります。 たとえば、ターゲット データベースのあるテーブルが、再作成時の準備中に削除されている場合があります。 その時点で更新を取り消すと、そのテーブルが失われることがあります。 このようなデータ損失が発生した場合、スキーマを再度比較する必要があります。