逐步解說:比較兩個資料庫的結構描述
這個主題適用於:
Visual Studio Ultimate |
Visual Studio Premium |
Visual Studio Professional |
Visual Studio Express |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
在本逐步解說中,您會使用 Visual Studio比較兩個資料庫的「結構描述」(Schema)。 結構描述比較動作也會從差異產生「資料定義語言」(Data Definition Language,DDL) 指令碼。 您可使用這個檔案來同步處理「目標」(Target) 與「來源」(Source) 的結構描述。 如需詳細資訊,請參閱比較和同步處理資料庫結構描述。
在這個逐步解說中,您將遵循下列程序:
建立簡易資料庫。 如果您已完成逐步解說:比較資料庫與資料庫專案的結構描述,則可以使用產生的資料庫並可略過這一部分的逐步解說。
建立空白資料庫。 來源是 CompareProjectDB 資料庫,而您將建立空白的資料庫做為目標。
比較兩個資料庫的結構描述。 藉由比較結構描述,您會發現兩個資料庫的結構差異、在資料表中顯示差異,並產生表示差異的資料定義語言 (DDL) 指令碼。
檢查同步指令碼。 您將檢查 DDL 指令碼,並可在執行前編輯指令碼。
更新目標資料庫。 您將執行 DDL 指令碼來變更目標的結構描述。
必要條件
您必須已安裝下列產品:
SQL Server 2008
在目標資料庫伺服器上建立和更新資料庫的權限
Visual Studio Premium 或 Visual Studio Ultimate
建立簡易資料庫
您將執行下列工作來建立簡易資料庫:
建立包含資料庫結構描述的指令碼
建立資料庫專案並匯入該結構描述
將資料庫專案部署至隔離的開發環境
建立包含資料庫結構描述的指令碼
若要建立您可以從中匯入結構描述的指令碼
在 [檔案] 功能表上指向 [新增],然後按一下 [檔案]。
[新增檔案] 對話方塊隨即出現。
按一下 [分類] 清單中的 [一般] (若尚未反白顯示)。
在 [範本] 清單中,按一下 [Sql 檔],然後再按一下 [開啟]。
Transact-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。
您可以將此檔案儲存至電腦上的任何位置。 請記下這個位置,因為您必須在下一個程序中使用這個指令碼。
按一下 [儲存]。
在 [檔案] 功能表上,按一下 [關閉方案]。
接著,您要建立資料庫專案,並從您已建立的指令碼匯入結構描述。
建立資料庫專案並匯入結構描述
若要建立資料庫專案
在 [檔案] 功能表中,指向 [新增],然後按一下 [專案]。
[新增專案] 對話方塊隨即出現。
展開 [已安裝的範本] 底下的 [資料庫] 節點,然後按一下 [SQL Server]。
在範本清單中,按一下 [SQL Server 2008 資料庫專案]。
在 [名稱] 中輸入 CompareProjectDB。
按一下 [方案] 清單中的 [建立方案] (若尚未反白顯示)。
選取 [為方案建立目錄] 核取方塊 (若尚未選取)。
清除 [加入至原始檔控制] 核取方塊 (若尚未清除),然後按一下 [確定]。
資料庫專案就會在 [方案總管] 中建立並出現。 接下來,您將從指令碼匯入資料庫結構描述。
若要從指令碼匯入資料庫結構描述
按一下 [專案] 功能表上的 [匯入指令碼]。
閱讀完 [歡迎] 頁面之後,按 [下一步]。
按一下 [瀏覽],並且指出您儲存 SampleImportScript.sql 檔案的路徑。
按兩下 SampleImportScript.sql 檔案,然後按一下 [完成]。
如此就會匯入指令碼,而且該指令碼中定義的物件會加入至資料庫專案。
檢閱摘要,然後按一下 [完成] 以完成作業。
注意事項
Sales.uspFillOrder 程序包含刻意設計的程式碼錯誤,您將在單元測試逐步解說中找到並更正此錯誤。
若要檢查產生的專案
在 [方案總管] 中,展開 [結構描述物件] 子節點。
瀏覽在階層架構中 [結構描述物件] 節點底下的子節點。
[方案總管] 包含定義資料庫物件的檔案。
按一下 [檢視] 功能表上的 [資料庫結構描述檢視]。
展開 [結構描述檢視] 中的 [CompareProjectDB] 節點。
瀏覽在階層架構中 [CompareProjectDB] 節點底下的子節點。
[結構描述檢視] 包含物件,這些物件是在 [方案總管] 出現的檔案中定義的。
部署至隔離的開發環境
接下來,您會部署專案,以便建立具有已匯入結構描述但不包含任何資料的資料庫。 您會在「隔離的開發環境」(Isolated Development Environment) 或沙箱中建立此資料庫。 因此,您可以在不受干擾的情況下開發及測試資料庫。
若要設定並建置資料庫專案
按一下 [方案總管] 中的資料庫專案 CompareProjectDB。
按一下 [專案] 功能表上的 [CompareProjectDB 屬性]。
此專案的屬性對話方塊隨即出現。
按一下 [部署] 索引標籤。
按一下 [為下列項目設定部署設定] 清單中的 [我的隔離開發環境]。 您可以針對隔離的開發環境進行設定,以便使用不同的部署設定,讓這些設定有別於其他環境 (例如測試或實際執行伺服器) 所使用的部署設定。
在 [部署動作] 清單中,按一下 [建立部署指令碼 (.sql) 並部署到資料庫]。
在 [目標資料庫設定] 中,按一下 [編輯]。
[連接屬性] 對話方塊隨即出現。
針對您要建立的資料庫設定其連接屬性,然後按一下 [確定]。
正確的連接字串就會出現在 [目標連接] 方塊中。
警告
您應該在測試伺服器、程式開發伺服器或本機電腦上建立資料庫。 您不應該指定實際執行伺服器。
在 [目標資料庫名稱] 中,輸入 CompareProjectDB。
按一下 [部署組態檔] 旁邊的 [編輯]。
清除 [如果可能發生資料遺失,則封鎖累加部署] 核取方塊。
注意事項
在這個逐步解說中,您將針對部署成資料庫單元測試一部分的空白資料庫測試預存程序。 您不需要保留任何現有的資料,因為您將在隔離的開發環境中測試預存程序。
在 [檔案] 功能表上按一下 [全部儲存]。
在 [建置] 功能表上,按一下 [建置方案]。
您剛才設定的屬性會決定部署指令碼的建置方式。 建置的狀態會出現在 [輸出] 視窗中,而且 [組建: 1 成功或最新狀態] 應該會出現在最後一行。
若要部署資料庫專案
按一下 [方案總管] 中的 CompareProjectDB 資料庫專案。
按一下 [建置] 功能表上的 [部署 CompareProjectDB]。
警告
您應該針對測試伺服器、程式開發伺服器或本機電腦執行這項部署, 您不應該指定實際執行伺服器。
資料庫專案即會部署到新的資料庫。 部署的狀態會出現在 [輸出] 視窗中,而且 [部署成功] 應該會出現在最後一行。 接下來,您會建立空白的資料庫,以便與這個部署的資料庫進行比較。
建立空白資料庫
若要建立空白資料庫
在 [檔案] 功能表上,指向 [新增],然後按一下 [專案]。
[新增專案] 對話方塊隨即出現。
展開 [已安裝的範本] 清單中的 [資料庫] 節點,然後按一下 [SQL Server]。
按一下 [SQL Server 2008 精靈]。
在 [名稱] 中輸入 EmptyDB。
接受其餘欄位的預設值,然後按一下 [確定]。
在 [新增資料庫專案精靈] 中,按一下 [設定組建/部署]。
在 [部署動作] 清單中,按一下 [建立部署指令碼 (.sql) 並部署到資料庫]。
按一下 [目標連接] 中的 [瀏覽] 按鈕。
指定要在其中建立空白資料庫的資料庫伺服器的連接,然後按一下 [完成]。
名為 EmptyDB 的資料庫專案隨即建立並出現在 [方案總管] 中。
按一下 [方案總管] 中的 EmptyDB 資料庫專案。
按一下 [建置] 功能表上的 [部署 EmptyDB]。
資料庫專案隨即建置並部署到指定的伺服器。
比較兩個資料庫的結構描述
若要比較兩個資料庫的結構描述
指向 [資料] 功能表上的 [結構描述比較],然後按一下 [新增結構描述比較]。
[新增結構描述比較] 對話方塊隨即顯示,以便您指定來源和目標。 在這個對話方塊中,指定來源和目標所在的伺服器、每個資料庫的名稱,以及連接到每個資料庫使用的驗證類型。
此外,[結構描述比較] 視窗也會在背景開啟,Visual Studio會自動指定像是 SchemaCompare1 的名稱。
按一下 [來源結構描述] 底下的 [資料庫],然後按一下對應到 CompareProjectDB 資料庫的連接。
如果清單中未顯示此種連接,請按一下 [新增連接]。 在 [連接屬性] 對話方塊中,識別 CompareProjectDB 資料庫所在的伺服器、連接到該資料庫時所要使用的驗證類型,以及資料庫本身。 完成後,請按一下 [確定]。
注意事項
在建立連接之後,連接會出現在 [伺服器總管] 的 [資料連接] 下方。
按一下 [目標結構描述] 底下的 [資料庫],然後按一下對應到 EmptyDB 資料庫的連接。
如果清單中未顯示此種連接,請按一下 [新增連接]。 在 [連接屬性] 對話方塊中,識別 EmptyDB 資料庫所在的伺服器、連接到該資料庫時所要使用的驗證類型,以及資料庫本身。 完成後,請按一下 [確定]。
按一下 [選項] 以指定要比較的物件、要略過的差異類型,和要在產生的更新指令碼中包含的內容。
注意事項
當您比較資料庫時,您不會指定 SQLCMD 變數。
在 [一般] 索引標籤上,展開 [比較選項] 節點。
選取 [忽略檔案和記錄檔的檔名和路徑]。
按一下 [確定]。
按一下 [確定]。
結構描述比較便開始。
注意事項
您可以停止正在進行的比較作業。請開啟 [資料] 功能表,指向 [結構描述比較],然後按一下 [停止結構描述比較]。
您可以設定選項來決定要將何者將視為差異,以及變更建立更新指令碼的方式。 如需詳細資訊,請參閱 HOW TO:設定用來比較資料庫結構描述的選項。
當比較完成時,[結構描述比較] 視窗中的資料表會顯示兩個資料庫的結構差異。 資料表中的每個資料列都代表各資料庫中的每一個「資料庫物件」(Database Object)。 資料庫物件會依照類型予以組織:資料表、檢視表、預存程序、角色等等。
更新目標資料庫
更新目標的結構描述時可有兩種選擇。 您可以直接從 [結構描述比較] 視窗更新結構描述,或使用 Transact-SQL 編輯器。 本節將說明這兩種選擇。
在執行結構描述比較之後,[結構描述比較] 視窗中的資料表會顯示結構差異。 對於 [CompareProjectDB (來源資料庫)] 資料行中的每一個物件,資料表會在 [更新動作] 資料行中顯示動作,這是在兩個資料庫中同步處理該物件所需的動作。 在此例中,由於目標是空的,其中只有預設物件,[狀態] 資料行大多會顯示 [新增] 狀態,而 [更新動作] 資料行則大多會顯示 [建立] 動作。
寫入更新至目標
您可以使用 [結構描述比較] 視窗所列的更新動作,更新目標的結構描述。 若要執行這項工作,請遵循寫入更新至目標資料庫中的步驟。
檢視指令碼,然後寫入更新至目標
您可以匯出更新指令碼、檢查並視需要變更指令碼,然後用來同步處理目標資料庫。 若要執行這些工作,請遵循檢查並執行同步指令碼中的步驟。
寫入更新至目標資料庫
![]() |
---|
在寫入更新至實際執行或開發伺服器之前,您應該考慮備份目標資料庫。 由於某些結構描述變更無法在單一交易中執行,因此如果啟動後再取消更新作業,則可能會遺失資料。 例如,可能已經卸除目標資料庫中的資料表,做為重新建立的準備。 如果這時取消更新,就可能會遺失該資料表。 在這個逐步解說中,您所更新的是空白的開發資料庫。 因此,您不會備份目標資料庫。 |
若要寫入更新至目標資料庫
在比較結果清單中,捲動至 [SQL 檔案] 節點。
對於 CompareProjectDB 檔案和 CompareProjectDB_Log 檔案,將更新動作從 [建立] 變更為 [略過]。
注意事項
如果您比較同一部資料庫伺服器上的兩個資料庫,則同步處理會失敗,這是因為目標資料和記錄檔已經存在並由來源資料庫使用中。 在這個逐步解說中,您只需略過檔案更新並同步處理資料庫的內容。
對於 EmptyDB 檔案和 EmptyDB_log 檔案,將更新動作從 [卸除] 變更為 [略過]。
注意事項
因為您不是從來源資料庫建立檔案,所以不得刪除目標資料庫的檔案。 在這個逐步解說中,您只需略過檔案更新並同步處理資料庫的內容。
按一下 [結構描述比較] 工具列上的 [寫入更新]。
[結構描述比較] 視窗中所列的更新動作即會執行。 同步處理會變更目標的結構描述,使其符合來源的結構描述。
注意事項
當更新動作執行時,您可以取消作業。請按一下 [資料] 功能表,指向 [結構描述比較],然後按一下 [停止寫入目標]。
如果要再次執行比較,驗證是否套用了選取的更新,您可以按一下 [結構描述比較] 工具列上的 [重新整理]。
檢查並執行同步指令碼
若要檢查同步指令碼
指向 [資料] 功能表上的 [結構描述比較],然後指向 [匯出至],然後按一下 [編輯器]。
此外,您也可以按一下 [結構描述比較] 工具列上的 [匯出至編輯器]。
Transact-SQL 編輯器會在中斷連接模式中開啟,並顯示此 Transact-SQL 同步指令碼。 這個視窗的名稱會類似於 Server.CompareProjectDB - SchemaUpdate_EmptyDB_1.sql, 並且顯示 Transact-SQL 指令碼。 由於您可以寫入和讀取這個視窗,因此可以變更指令碼。 如果變更了指令碼,請開啟 [檔案] 功能表,然後按一下 [儲存]。 當您儲存檔案時,您可以指定其路徑和名稱。
在 [Transact-SQL 編輯器] 工具列上,按一下 [SQLCMD 模式]。
如果您未啟用 SQLCMD 模式,在嘗試執行指令碼時便會出現錯誤。
若要同步處理兩個資料庫的結構描述,請按一下 [Transact-SQL 編輯器] 工具列上的 [執行 SQL] 或按 F5 鍵執行這個指令碼。
[連接至資料庫] 對話方塊隨即出現。
按一下對應到 EmptyDB 資料庫的連接,然後按一下 [確定]。
警告
如果您嘗試對不同的資料庫執行更新指令碼,有可能會造成非預期的結果。
比較並不會自動重新整理。 如果要再次執行比較,驗證是否套用了選取的更新,您必須按一下 [結構描述比較] 工具列上的 [重新整理]。
後續步驟
現在就可以比較兩個資料庫中的資料。 如需詳細資訊,請參閱 HOW TO:比較及同步處理兩個資料庫的資料。