共用方式為


逐步解說:比較兩個資料庫的結構描述

這個主題適用於:

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

建立簡易資料庫

您將執行下列工作來建立簡易資料庫:

  • 建立包含資料庫結構描述的指令碼

  • 建立資料庫專案並匯入該結構描述

  • 將資料庫專案部署至隔離的開發環境

建立包含資料庫結構描述的指令碼

若要建立您可以從中匯入結構描述的指令碼

  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. 清除 [加入至原始檔控制] 核取方塊 (若尚未清除),然後按一下 [確定]。

    資料庫專案就會在 [方案總管] 中建立並出現。 接下來,您將從指令碼匯入資料庫結構描述。

若要從指令碼匯入資料庫結構描述

  1. 按一下 [專案] 功能表上的 [匯入指令碼]。

  2. 閱讀完 [歡迎] 頁面之後,按 [下一步]。

  3. 按一下 [瀏覽],並且指出您儲存 SampleImportScript.sql 檔案的路徑。

  4. 按兩下 SampleImportScript.sql 檔案,然後按一下 [完成]。

    如此就會匯入指令碼,而且該指令碼中定義的物件會加入至資料庫專案。

  5. 檢閱摘要,然後按一下 [完成] 以完成作業。

    注意事項注意事項

    Sales.uspFillOrder 程序包含刻意設計的程式碼錯誤,您將在單元測試逐步解說中找到並更正此錯誤。

若要檢查產生的專案

  1. 在 [方案總管] 中,展開 [結構描述物件] 子節點。

  2. 瀏覽在階層架構中 [結構描述物件] 節點底下的子節點。

    [方案總管] 包含定義資料庫物件的檔案。

  3. 按一下 [檢視] 功能表上的 [資料庫結構描述檢視]。

  4. 展開 [結構描述檢視] 中的 [CompareProjectDB] 節點。

  5. 瀏覽在階層架構中 [CompareProjectDB] 節點底下的子節點。

    [結構描述檢視] 包含物件,這些物件是在 [方案總管] 出現的檔案中定義的。

部署至隔離的開發環境

接下來,您會部署專案,以便建立具有已匯入結構描述但不包含任何資料的資料庫。 您會在「隔離的開發環境」(Isolated Development Environment) 或沙箱中建立此資料庫。 因此,您可以在不受干擾的情況下開發及測試資料庫。

若要設定並建置資料庫專案

  1. 按一下 [方案總管] 中的資料庫專案 CompareProjectDB。

  2. 按一下 [專案] 功能表上的 [CompareProjectDB 屬性]。

    此專案的屬性對話方塊隨即出現。

  3. 按一下 [部署] 索引標籤。

  4. 按一下 [為下列項目設定部署設定] 清單中的 [我的隔離開發環境]。 您可以針對隔離的開發環境進行設定,以便使用不同的部署設定,讓這些設定有別於其他環境 (例如測試或實際執行伺服器) 所使用的部署設定。

  5. 在 [部署動作] 清單中,按一下 [建立部署指令碼 (.sql) 並部署到資料庫]。

  6. 在 [目標資料庫設定] 中,按一下 [編輯]。

    [連接屬性] 對話方塊隨即出現。

  7. 針對您要建立的資料庫設定其連接屬性,然後按一下 [確定]。

    正確的連接字串就會出現在 [目標連接] 方塊中。

    警告

    您應該在測試伺服器、程式開發伺服器或本機電腦上建立資料庫。 您不應該指定實際執行伺服器。

  8. 在 [目標資料庫名稱] 中,輸入 CompareProjectDB。

  9. 按一下 [部署組態檔] 旁邊的 [編輯]。

  10. 清除 [如果可能發生資料遺失,則封鎖累加部署] 核取方塊。

    注意事項注意事項

    在這個逐步解說中,您將針對部署成資料庫單元測試一部分的空白資料庫測試預存程序。 您不需要保留任何現有的資料,因為您將在隔離的開發環境中測試預存程序。

  11. 在 [檔案] 功能表上按一下 [全部儲存]。

  12. 在 [建置] 功能表上,按一下 [建置方案]。

    您剛才設定的屬性會決定部署指令碼的建置方式。 建置的狀態會出現在 [輸出] 視窗中,而且 [組建: 1 成功或最新狀態] 應該會出現在最後一行。

若要部署資料庫專案

  1. 按一下 [方案總管] 中的 CompareProjectDB 資料庫專案。

  2. 按一下 [建置] 功能表上的 [部署 CompareProjectDB]。

    警告

    您應該針對測試伺服器、程式開發伺服器或本機電腦執行這項部署, 您不應該指定實際執行伺服器。

    資料庫專案即會部署到新的資料庫。 部署的狀態會出現在 [輸出] 視窗中,而且 [部署成功] 應該會出現在最後一行。 接下來,您會建立空白的資料庫,以便與這個部署的資料庫進行比較。

建立空白資料庫

若要建立空白資料庫

  1. 在 [檔案] 功能表上,指向 [新增],然後按一下 [專案]。

    [新增專案] 對話方塊隨即出現。

  2. 展開 [已安裝的範本] 清單中的 [資料庫] 節點,然後按一下 [SQL Server]。

  3. 按一下 [SQL Server 2008 精靈]。

  4. 在 [名稱] 中輸入 EmptyDB。

  5. 接受其餘欄位的預設值,然後按一下 [確定]。

  6. 在 [新增資料庫專案精靈] 中,按一下 [設定組建/部署]。

  7. 在 [部署動作] 清單中,按一下 [建立部署指令碼 (.sql) 並部署到資料庫]。

  8. 按一下 [目標連接] 中的 [瀏覽] 按鈕。

  9. 指定要在其中建立空白資料庫的資料庫伺服器的連接,然後按一下 [完成]。

    名為 EmptyDB 的資料庫專案隨即建立並出現在 [方案總管] 中。

  10. 按一下 [方案總管] 中的 EmptyDB 資料庫專案。

  11. 按一下 [建置] 功能表上的 [部署 EmptyDB]。

    資料庫專案隨即建置並部署到指定的伺服器。

比較兩個資料庫的結構描述

若要比較兩個資料庫的結構描述

  1. 指向 [資料] 功能表上的 [結構描述比較],然後按一下 [新增結構描述比較]。

    [新增結構描述比較] 對話方塊隨即顯示,以便您指定來源和目標。 在這個對話方塊中,指定來源和目標所在的伺服器、每個資料庫的名稱,以及連接到每個資料庫使用的驗證類型。

    此外,[結構描述比較] 視窗也會在背景開啟,Visual Studio會自動指定像是 SchemaCompare1 的名稱。

  2. 按一下 [來源結構描述] 底下的 [資料庫],然後按一下對應到 CompareProjectDB 資料庫的連接。

    如果清單中未顯示此種連接,請按一下 [新增連接]。 在 [連接屬性] 對話方塊中,識別 CompareProjectDB 資料庫所在的伺服器、連接到該資料庫時所要使用的驗證類型,以及資料庫本身。 完成後,請按一下 [確定]。

    注意事項注意事項

    在建立連接之後,連接會出現在 [伺服器總管] 的 [資料連接] 下方。

  3. 按一下 [目標結構描述] 底下的 [資料庫],然後按一下對應到 EmptyDB 資料庫的連接。

    如果清單中未顯示此種連接,請按一下 [新增連接]。 在 [連接屬性] 對話方塊中,識別 EmptyDB 資料庫所在的伺服器、連接到該資料庫時所要使用的驗證類型,以及資料庫本身。 完成後,請按一下 [確定]。

  4. 按一下 [選項] 以指定要比較的物件、要略過的差異類型,和要在產生的更新指令碼中包含的內容。

    注意事項注意事項

    當您比較資料庫時,您不會指定 SQLCMD 變數。

  5. 在 [一般] 索引標籤上,展開 [比較選項] 節點。

  6. 選取 [忽略檔案和記錄檔的檔名和路徑]。

  7. 按一下 [確定]。

  8. 按一下 [確定]。

    結構描述比較便開始。

    注意事項注意事項

    您可以停止正在進行的比較作業。請開啟 [資料] 功能表,指向 [結構描述比較],然後按一下 [停止結構描述比較]。

    您可以設定選項來決定要將何者將視為差異,以及變更建立更新指令碼的方式。 如需詳細資訊,請參閱 HOW TO:設定用來比較資料庫結構描述的選項

    當比較完成時,[結構描述比較] 視窗中的資料表會顯示兩個資料庫的結構差異。 資料表中的每個資料列都代表各資料庫中的每一個「資料庫物件」(Database Object)。 資料庫物件會依照類型予以組織:資料表、檢視表、預存程序、角色等等。

更新目標資料庫

更新目標的結構描述時可有兩種選擇。 您可以直接從 [結構描述比較] 視窗更新結構描述,或使用 Transact-SQL 編輯器。 本節將說明這兩種選擇。

在執行結構描述比較之後,[結構描述比較] 視窗中的資料表會顯示結構差異。 對於 [CompareProjectDB (來源資料庫)] 資料行中的每一個物件,資料表會在 [更新動作] 資料行中顯示動作,這是在兩個資料庫中同步處理該物件所需的動作。 在此例中,由於目標是空的,其中只有預設物件,[狀態] 資料行大多會顯示 [新增] 狀態,而 [更新動作] 資料行則大多會顯示 [建立] 動作。

寫入更新至目標

您可以使用 [結構描述比較] 視窗所列的更新動作,更新目標的結構描述。 若要執行這項工作,請遵循寫入更新至目標資料庫中的步驟。

檢視指令碼,然後寫入更新至目標

您可以匯出更新指令碼、檢查並視需要變更指令碼,然後用來同步處理目標資料庫。 若要執行這些工作,請遵循檢查並執行同步指令碼中的步驟。

寫入更新至目標資料庫

注意事項注意事項

在寫入更新至實際執行或開發伺服器之前,您應該考慮備份目標資料庫。 由於某些結構描述變更無法在單一交易中執行,因此如果啟動後再取消更新作業,則可能會遺失資料。 例如,可能已經卸除目標資料庫中的資料表,做為重新建立的準備。 如果這時取消更新,就可能會遺失該資料表。 在這個逐步解說中,您所更新的是空白的開發資料庫。 因此,您不會備份目標資料庫。

若要寫入更新至目標資料庫

  1. 在比較結果清單中,捲動至 [SQL 檔案] 節點。

  2. 對於 CompareProjectDB 檔案和 CompareProjectDB_Log 檔案,將更新動作從 [建立] 變更為 [略過]。

    注意事項注意事項

    如果您比較同一部資料庫伺服器上的兩個資料庫,則同步處理會失敗,這是因為目標資料和記錄檔已經存在並由來源資料庫使用中。 在這個逐步解說中,您只需略過檔案更新並同步處理資料庫的內容。

  3. 對於 EmptyDB 檔案和 EmptyDB_log 檔案,將更新動作從 [卸除] 變更為 [略過]。

    注意事項注意事項

    因為您不是從來源資料庫建立檔案,所以不得刪除目標資料庫的檔案。 在這個逐步解說中,您只需略過檔案更新並同步處理資料庫的內容。

  4. 按一下 [結構描述比較] 工具列上的 [寫入更新]。

    [結構描述比較] 視窗中所列的更新動作即會執行。 同步處理會變更目標的結構描述,使其符合來源的結構描述。

    注意事項注意事項

    當更新動作執行時,您可以取消作業。請按一下 [資料] 功能表,指向 [結構描述比較],然後按一下 [停止寫入目標]。

    如果要再次執行比較,驗證是否套用了選取的更新,您可以按一下 [結構描述比較] 工具列上的 [重新整理]。

檢查並執行同步指令碼

若要檢查同步指令碼

  1. 指向 [資料] 功能表上的 [結構描述比較],然後指向 [匯出至],然後按一下 [編輯器]。

    此外,您也可以按一下 [結構描述比較] 工具列上的 [匯出至編輯器]。

    Transact-SQL 編輯器會在中斷連接模式中開啟,並顯示此 Transact-SQL 同步指令碼。 這個視窗的名稱會類似於 Server.CompareProjectDB - SchemaUpdate_EmptyDB_1.sql, 並且顯示 Transact-SQL 指令碼。 由於您可以寫入和讀取這個視窗,因此可以變更指令碼。 如果變更了指令碼,請開啟 [檔案] 功能表,然後按一下 [儲存]。 當您儲存檔案時,您可以指定其路徑和名稱。

  2. 在 [Transact-SQL 編輯器] 工具列上,按一下 [SQLCMD 模式]。

    如果您未啟用 SQLCMD 模式,在嘗試執行指令碼時便會出現錯誤。

  3. 若要同步處理兩個資料庫的結構描述,請按一下 [Transact-SQL 編輯器] 工具列上的 [執行 SQL] 或按 F5 鍵執行這個指令碼。

    [連接至資料庫] 對話方塊隨即出現。

  4. 按一下對應到 EmptyDB 資料庫的連接,然後按一下 [確定]。

    警告

    如果您嘗試對不同的資料庫執行更新指令碼,有可能會造成非預期的結果。

    比較並不會自動重新整理。 如果要再次執行比較,驗證是否套用了選取的更新,您必須按一下 [結構描述比較] 工具列上的 [重新整理]。

後續步驟

現在就可以比較兩個資料庫中的資料。 如需詳細資訊,請參閱 HOW TO:比較及同步處理兩個資料庫的資料

請參閱

工作

HOW TO:比較及同步處理兩個資料庫的資料

HOW TO:比較資料庫結構描述

逐步解說:比較兩個資料庫的資料

逐步解說:比較資料庫與資料庫專案的結構描述

概念

使用參考資料庫中的資料比較和同步處理一個或多個資料表中的資料

在 Visual Studio 中建立和管理資料庫與資料層應用程式