逐步解說:套用資料庫重構技術

當您設計及更新資料庫結構描述時,使用 Visual Studio Premium 或 Visual Studio Ultimate 中的重構技術,可以減少必須執行的重複且容易發生錯誤的工作。 例如,如果資料庫物件的名稱必須變更或此物件必須移至不同的結構描述,您可以使用重構來更新其參考。 如果採用這種方法,可以增加速度以及資料庫設計例行性變更的正確性。

這個逐步解說說明資料庫開發的一般案例。 若要在現有資料庫中加入功能,您必須執行初始實作,然後與另一位小組成員一起檢閱。 在檢閱期間,您將識別必須先解決的數個問題,然後再簽入變更。 接著,使用各種重構技術來變更結構描述。

這個逐步解說將說明下列工作:

  • 匯入資料庫結構描述

  • 實作一般資料庫開發工作

  • 修正程式碼錯誤

  • 完成開發工作

  • 對程式碼檢閱意見做出回應

必要條件

若要完成這個逐步解說,您需要下列項目:

  • Visual Studio Premium 或 Visual Studio Ultimate

  • 已安裝 AdventureWorks2008 資料庫之資料庫伺服器的唯讀權限。

匯入資料庫結構描述

在小組環境中變更結構描述之前,您通常會先將現有的專案簽出版本控制系統。 在本逐步解說序中,您會建立資料庫專案並從 AdventureWorks2008 範例資料庫匯入結構描述。

若要建立資料庫專案

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

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

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

  3. 在範本清單中,按一下 [SQL Server 2008 資料庫專案]。

  4. 在 [名稱] 中輸入 RefactorAdventureWorks,再按一下 [確定]。

    隨即建立方案,其中包含名稱為 RefactorAdventureWorks 的空白資料庫專案,做為測試 (也稱為沙箱) 專案。

    接下來,您要從 AdventureWorks 資料庫的已部署執行個體匯入結構描述。

若要匯入 AdventureWorks 資料庫

  1. 按一下 [方案總管] 或 [結構描述檢視] 中的 [RefactorAdventureWorks]。

  2. 按一下 [專案] 功能表上的 [匯入資料庫物件和設定]。

    注意事項注意事項

    您也可以用滑鼠右鍵按一下 [RefactorAdventureWorks],然後按一下 [匯入資料庫物件和設定]。

    [匯入資料庫] 精靈隨即出現。

  3. 在 [來源資料庫連接] 清單中,按一下對應到 AdventureWorks 資料庫的連接。

    重要事項重要事項

    如果您尚未連接到該資料庫,必須先按一下 [新增連接] 建立資料庫的連接。 如需詳細資訊,請參閱 HOW TO:建立資料庫連接

  4. 按一下 [啟動] 完成物件和設定匯入,然後按一下 [完成]。

    當匯入結構描述時,對應到資料庫物件的專案項目會出現在 [方案總管] 和 [結構描述檢視] 中的資料庫專案底下。

    注意事項注意事項

    即使您已連接此資料庫來匯入結構描述,您現在還是會中斷連接並離線工作。

    接下來將執行資料庫開發的一般工作,並在資料庫專案中加入程式碼。

實作一般資料庫開發工作

在此工作中,要求您實作支援,以追蹤每個員工的缺勤記錄。 在這項工作中,必須建立下列物件:

  • 追蹤每個缺勤開始和結束日期以及缺勤類型 (年假、病假、陪審團任務、浮動假、留職停薪或喪假) 的資料表。 稍後您將在本逐步解說中將此資料表加入至 Person 結構描述。 資料表中的資料有下列限制:

    • 缺勤絕不超過五天之久 (較長的缺勤要分為多個項目)。

    • 缺勤具有有效的日期範圍。

    • 此資料表透過 EmployeeID 與 Employee 資料表產生關聯。

  • 顯示每個員工完整缺勤記錄的檢視表。

  • 記錄缺勤並在缺勤類型為年假時更新員工年假時數的預存程序。

若要準備加入程式碼

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

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

  3. 如果 [結構描述檢視] 是根據物件型別排序,請按一下工具列上的 [變更物件群組]。

    注意事項注意事項

    如果 [結構描述檢視] 包含名稱為「資料表」和「檢視」的節點,它就是根據物件型別加以排序。 如果 [結構描述檢視] 包含名稱為「結構描述」的節點,您可以繼續進行下一個程序。

    接下來將 AbsenceHistory 資料表加入至資料庫專案。

若要加入 AbsenceHistory 資料表

  1. 在 [結構描述檢視] 中依序展開 [結構描述] 節點、[Person] 子節點和 [資料表] 子節點。

  2. 以滑鼠右鍵按一下 [資料表] 子節點,指向 [加入],然後按一下 [資料表]。

    [加入新項目] 對話方塊隨即出現。

  3. 在 [名稱] 中,輸入 AbsenceHistory,然後按一下 [加入]。

    Transact-SQL 編輯器隨即開啟,並顯示 AbsenceHistory 資料表的定義。

  4. 在 Transact-SQL 編輯器中,以下列程式碼取代現有的資料表定義:

    CREATE TABLE [Person].[AbsenceHistory]
    (
    [EmployeeID] INT NOT NULL, 
    [BeginDate] DateTime NOT NULL,
    [EndDate] DateTime NOT NULL,
    [AbsenceType] NCHAR(1) NOT NULL
    );
    
  5. 按一下 [檔案] 功能表上的 [儲存 Person.AbsenceHistory.table.sql]。

    接下來,您要將檢查條件約束加入至 AbsenceHistory 資料表。

若要將檢查條件約束加入至資料表

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

  2. 以滑鼠右鍵按一下 [條件約束] 節點,指向 [加入],然後按一下 [檢查條件約束]。

    [加入新項目] 對話方塊隨即出現。

  3. 在 [名稱] 中輸入 CK_AbsenceHistory_ValidDates,然後按一下 [加入]。

    Transact-SQL 編輯器隨即開啟,並顯示此條件約束的定義。

  4. 在 Transact-SQL 編輯器中,以下列程式碼取代現有的條件約束定義:

    ALTER TABLE [Person].[AbsenceHistory]
    ADD CONSTRAINT [CK_AbsenceHistory_ValidDates] 
    CHECK  (EndDate >= BeginDate AND DateDiff(day, EndDate, BeginDate) <= 5)
    go
    EXECUTE sp_addextendedproperty @name = N'MS_Description', 
    @value = 'Check constraint [EndDate]>= [BeginDate]', 
    @level0type = N'SCHEMA', 
    @level0name = N'Person', 
    @level1type = N'TABLE', 
    @level1name = N'AbsenceHistory', 
    @level2type = N'CONSTRAINT', 
    @level2name = N'CK_AbsenceHistory_ValidDates';
    

    此程式碼會在資料表上定義條件約束,確保結束日期晚於開始日期,而且其間差異不超過五天。

  5. 按一下 [檔案] 功能表上的 [儲存 Person.AbsenceHistory.CK_AbsenceHistory_ValidDates.chkconst.sql]。

    接下來將外部索引鍵加入至 AbsenceHistory 資料表。

若要加入外部索引鍵的定義

  1. 在 [結構描述檢視] 中,以滑鼠右鍵按一下 [索引鍵] 節點,指向 [加入],然後按一下 [外部索引鍵]。

    [加入新項目] 對話方塊隨即出現。

  2. 在 [名稱] 中輸入 FK_AbsenceHistory_Employee_EmployeeID,然後按一下 [加入]。

    Transact-SQL 編輯器隨即開啟,並顯示此外部索引鍵的定義。

  3. 在 Transact-SQL 編輯器中,以下列程式碼取代現有的外部索引鍵定義:

    ALTER TABLE [Person].[AbsenceHistory]
    ADD CONSTRAINT [FK_AbsenceHistory_Employee_EmployeeID] 
    FOREIGN KEY ([EmployeeID]) 
    REFERENCES [HumanResources].[Employee] ([BusinessEntityID]) 
    ON DELETE NO ACTION ON UPDATE NO ACTION;
    
    GO
    EXECUTE sp_addextendedproperty @name = N'MS_Description', 
        @value = 'Foreign key constraint referencing Employee.BusinessEntityID.', 
        @level0type = N'SCHEMA', 
        @level0name = N'Person', 
        @level1type = N'TABLE', 
        @level1name = N'AbsenceHistory', 
        @level2type = N'CONSTRAINT', 
        @level2name = N'FK_AbsenceHistory_Employee_EmployeeID';
    

    此程式碼會定義 AbsenceHistory 資料表的 EmployeeID 與 [HumanResources].[Employee] 資料表的 BusinessEntityID 之間的外部索引鍵關聯性。

  4. 按一下 [檔案] 功能表上的 [儲存 Person.AbsenceHistory.FK_AbsenceHistory_Employee_EmployeeID.fkey.sql]。

    此時,您發覺資料表應該位於 HumanResources 結構描述。 在下一個程序中,您將修正這個錯誤。

修正程式碼錯誤

因為您已經定義條件約束和外部索引鍵,移動資料表及其相關物件至不同的結構描述通常會消耗大量時間。 您可以使用資料庫重構,快速輕鬆地將資料表及其相關物件移至正確的結構描述,然後繼續進行。

若要將 AbsenceHistory 資料表移至 HumanResources 結構描述

  1. 在 [結構描述檢視] 中,以滑鼠右鍵按一下 AbsenceHistory 資料表,指向 [重構],然後按一下 [移至結構描述]。

    [移至結構描述] 對話方塊隨即出現。

  2. 在 [新結構描述] 清單中,按一下 [HumanResources]。

  3. 確認已選取 [預覽變更] 核取方塊,然後按一下 [確定]。

    [預覽變更] 對話方塊隨即出現。 您可以先檢閱變更,再將變更套用至您的資料庫專案。

  4. 按一下 [套用]。

    重構變更隨即套用至您的資料庫專案。 AbsenceHistory 資料表 (以及所有相關物件) 會從 Person 結構描述移至 HumanResources 結構描述。

  5. 在 [結構描述檢視] 中,依序展開 [HumanResources] 結構描述節點和 [資料表] 節點。

    AbsenceHistory 資料表會出現在正確的結構描述中。

    注意事項注意事項

    當您將物件移至正確的結構描時,並未變更定義物件之檔案的名稱。 如果要更新檔案名稱,必須在 [方案總管] 中重新命名。

    接下來,您將完成開發工作的其餘步驟。

完成開發工作

現在您已修正資料表的結構描述,必須建立下列物件:

  • 顯示每個員工完整缺勤記錄的檢視表。

  • 記錄缺勤並在缺勤類型為年假時更新員工年假時數的預存程序。

若要加入 vEmployeeAbsenceHistory 檢視表

  1. 在 [結構描述檢視] 中,展開 HumanResources 結構描述中的 [檢視] 節點。

  2. 以滑鼠右鍵按一下 [檢視] 節點,指向 [加入],然後按一下 [檢視]。

    [加入新項目] 對話方塊隨即出現。

  3. 在 [名稱] 中輸入 vEmployeeAbsenceHistory,然後按一下 [加入]。

    Transact-SQL 編輯器隨即開啟,並顯示此檢視表的定義。

  4. 在 Transact-SQL 編輯器中,以下列程式碼取代現有的檢視表定義:

    CREATE VIEW [HumanResources].[vEmployeeAbsenceHistory]
    AS 
    SELECT 
        a.* 
        ,c.[Title] 
        ,c.[FirstName] 
        ,c.[MiddleName] 
        ,c.[LastName] 
        ,c.[Suffix] 
    FROM [HumanResources].[Employee] e
        INNER JOIN [Person].[Person] c 
        ON c.[BusinessEntityID] = e.[BusinessEntityID]
        INNER JOIN [AbsenceHistory] a 
        ON e.[BusinessEntityID] = a.[EmployeeID] 
    ;
    
    GO
    EXECUTE sp_addextendedproperty @name = N'MS_Description', 
    @value = 'Returns employee name and absence history.', 
    @level0type = N'SCHEMA', 
    @level0name = N'HumanResources', 
    @level1type = N'VIEW', 
    @level1name = N'vEmployeeAbsenceHistory';
    

    此程式碼定義會從 Employee、Contact 和 AbsenceHistory 資料表的組合中傳回資料的檢視表。

  5. 在 [檔案] 功能表上,按一下 [儲存 HumanResources.vEmployeeAbsenceHistory.view.sql]。

    接下來,您要加入預存程序。

若要加入 uspRecordAbsence 預存程序

  1. 在 [結構描述檢視] 中,依序展開 HumanResources 結構描述中的 [可程式性] 節點和 [預存程序] 節點。

  2. 以滑鼠右鍵按一下 [預存程序] 節點,指向 [加入],然後按一下 [預存程序]。

    [加入新項目] 對話方塊隨即出現。

  3. 在 [名稱] 中輸入 uspRecordAbsence,然後按一下 [加入]。

    Transact-SQL 編輯器隨即開啟,並顯示此預存程序的定義。

  4. 在 Transact-SQL 編輯器中,以下列程式碼取代現有的預存程序定義:

    CREATE PROCEDURE [HumanResources].[uspRecordAbsence]
    @EmployeeID INT,
    @AbsenceType NCHAR(1),
    @StartDate DATETIME,
    @EndDate DATETIME
    AS
    BEGIN
    BEGIN TRANSACTION
    INSERT INTO [AbsenceHistory] (EmployeeID, BeginDate, EndDate, AbsenceType)
    VALUES(@EmployeeID, @StartDate, @EndDate, @AbsenceType)
    IF (@AbsenceType = 'V')
    BEGIN
    UPDATE [Employee]
    SET [VacationHours] = [VacationHours] - DateDiff(day, @StartDate, @EndDate)
    WHERE [BusinessEntityID] = @EmployeeID
    END
    COMMIT TRANSACTION
    END;
    

    此程式碼定義了預存程序,這個預存程序會在 AbsenceHistory 資料表中加入資料列,並在缺勤類型為 'V' 時更新 Employee 資料表的 VacationHours 欄位。

  5. 按一下 [檔案] 功能表上的 [儲存 dbo.uspRecordAbsence.proc.sql]。

    在下一個程序中,您要對程式碼檢閱中收到的意見做出回應。

對程式碼檢閱意見做出回應

當您與另一位小組成員一起檢閱程式碼時,得到數個有關最佳做法的意見。 他要求您避免使用 SELECT *,因為這會在資料庫程式碼執行靜態程式碼分析時產生警告。 此外,也要求您完整限定預存程序中所使用的名稱。 最後,他要求您將 AbsenceHistory 資料表中的 BeginDate 資料行重新命名為 StartDate。

注意事項注意事項

編碼標準和需求因小組而異。 您應該將組織的編碼標準套用至撰寫的 Transact-SQL 程式碼。 這個逐步解說說明兩個問題。 此外,您通常會將這些技術套用至所有新程式碼 (例如完整限定新程式碼中的所有名稱),而不只是單一資料庫物件。

同樣地,這些變更類型實作時可能相當繁瑣且容易發生錯誤。 您可以使用資料庫重構,快速輕鬆更新資料庫程式碼、測試程式碼和資料產生計劃。

若要在檢視表定義中展開 SELECT *

  1. 按兩下 [結構描述檢視] 中的 [vEmployeeAbsenceHistory] 檢視表。

    Transact-SQL 編輯器隨即開啟,並顯示此檢視表的定義。

  2. 指向 [資料] 功能表上的 [重構],然後按一下 [展開萬用字元]。

    [預覽變更] 對話方塊隨即出現。

  3. 按一下 [展開萬用字元] 清單中的 [a.*]。

    [預覽變更] 窗格會顯示將套用至檢視表的更新。

  4. 按一下 [套用]。

    變更隨即套用至您的資料庫專案。 接下來,您將完整限定在本逐步解說稍早的程序中所定義之預存程序中的名稱。

若要完整限定預存程序中的名稱

  1. 按兩下 [結構描述檢視] 中的 [uspRecordAbsence] 預存程序。

    Transact-SQL 編輯器隨即開啟,並顯示此預存程序的定義。

  2. 指向 [資料] 功能表上的 [重構],然後按一下 [完整限定名稱]。

    [預覽變更] 對話方塊隨即出現,並顯示套用重構作業至專案時將進行的所有變更。

  3. 檢閱變更之後,按一下 [套用]。

    變更隨即套用至您的資料庫專案。

若要重新命名 BeginDate 資料行

  1. 在 [結構描述檢視] 中,依序展開 [AbsenceHistory] 資料表和 [資料行] 節點,然後按一下 [BeginDate] 資料行。

  2. 指向 [資料] 功能表上的 [重構],然後按一下 [重新命名]。

    [重新命名] 對話方塊隨即出現。

    注意事項注意事項

    您也可以用滑鼠右鍵按一下 [結構描述檢視] 中的 BeginDate,然後指向 [重構],再按一下 [重新命名]。

  3. 在 [新名稱] 中,輸入 StartDate。

  4. 選取 [預覽變更] 核取方塊,然後按一下 [確定]。

    [預覽變更] 對話方塊隨即出現,並顯示套用重新命名作業至資料庫專案時將進行的所有變更。

  5. 按一下 [套用]。

    隨即進行變更。 即會更新資料行名稱,而每一個已更新之物件的新資料行名稱都會出現在 [結構描述檢視] 中。 如果您開啟在本主題中稍早所指定之日期條件約束的定義,此條件約束已經更新為參考新資料行名稱。

後續步驟

此時,您通常會與執行程式碼檢閱的小組成員一起檢閱更新,然後將變更簽入版本控制。 此時,您已經更新資料庫專案,即資料庫結構描述的離線表示。 您必須將資料庫專案部署至目標資料庫,更新已部署的結構描述。

當您將重構作業套用至資料庫專案時,如果您使用 sp_rename 或 ALTER 重新命名物件或移動物件,則重構記錄檔會記錄該作業的相關資訊。 在這個逐步解說中,記錄檔的名稱為 RefactorAdventureWorks.refactorlog。 重構記錄檔用於重構階段嘗試保留您的重構變更意圖。 例如,如果您重新命名資料行,重構記錄就會記錄此變更。 在部署階段,這項資訊會防止卸除舊名稱的資料行 (以及它所包含的任何資料) 以及建立新名稱的空白資料行。 如果使用重構,不需要在預先部署和部署後指令碼中加入陳述式,即可保留資料。

請參閱

工作

HOW TO:將重構變更部署至資料庫

概念

將資料庫物件移至其他結構描述

提供資料庫物件的完整名稱

在 SELECT 陳述式中展開萬用字元

分析資料庫程式碼以改善程式碼品質