共用方式為


逐步解說:擴充資料庫專案部署以分析部署計劃

您可以建立部署參與者,以在部署 SQL 專案時執行自定義動作。 您可以建立一個 DeploymentPlanModifier 或一個 DeploymentPlanExecutor。 使用 DeploymentPlanModifier 在執行計劃之前變更計劃,並使用 DeploymentPlanExecutor 在執行計劃時執行作業。 在本逐步解說中,您會建立名為 DeploymentUpdateReportContributor 的 DeploymentPlanExecutor,以建立部署資料庫專案時所執行動作的相關報表。 因為此組建參與者接受參數來控制是否產生報表,所以您必須執行另一個必要的步驟。

在本逐步解說中,您會完成下列主要工作:

先決條件

您需要下列元件才能完成本逐步解說:

  • 您必須已安裝包含 SQL Server Data Tools (SSDT) 的 Visual Studio 版本,並支援 C# 或 VB 開發。
  • 您必須有包含 SQL 物件的 SQL 專案。
  • 您可以部署資料庫專案的 SQL Server 實例。

注意

本逐步解說適用於已經熟悉 SSDT SQL 功能的使用者。 您也應該熟悉基本的 Visual Studio 概念,例如如何建立類別程式庫,以及如何使用程式碼編輯器將程式碼新增至類別。

建立部署貢獻者

若要建立部署參與者,您必須執行下列任務:

  • 建立類別庫專案,並新增必要的參考。

  • 定義名為 DeploymentUpdateReportContributor 的類別,其繼承自 DeploymentPlanExecutor

  • 覆寫 OnExecute 方法。

  • 新增私有輔助類別。

  • 建置產生的組件。

建立類別庫專案

  1. 建立名為 MyDeploymentContributor 的 Visual Basic 或 C# 類別程式庫專案。

  2. 將檔案 「Class1.cs」 重新命名為 「DeploymentUpdateReportContributor.cs」。

  3. 在 [方案總管] 中,以滑鼠右鍵按一下專案節點,然後選取 [新增參考]。

  4. 在 [架構] 索引標籤上選取 System.ComponentModel.Composition

  5. 新增必要的 SQL 參考:以滑鼠右鍵按一下專案節點,然後選取 [新增參考]。 選取 [瀏覽],然後流覽至 C:\Program Files (x86)\Microsoft SQL Server\110\DAC\Bin 資料夾。 選擇 Microsoft.SqlServer.Dac.dllMicrosoft.SqlServer.Dac.Extensions.dllMicrosoft.Data.Tools.Schema.Sql.dll 專案,選取 [新增],然後選取 [確定]。

    接下來,開始將程式代碼新增至 類別。

定義 DeploymentUpdateReportContributor 類別

  1. 在程式代碼編輯器中,使用 語句更新 DeploymentUpdateReportContributor.cs 檔案,以符合下列

    using System;
    using System.IO;
    using System.Text;
    using System.Xml;
    using Microsoft.SqlServer.Dac.Deployment;
    using Microsoft.SqlServer.Dac.Extensibility;
    using Microsoft.SqlServer.Dac.Model;
    
  2. 更新類別定義以符合下列程式碼:

    /// <summary>
        /// An executor that generates a report detailing the steps in the deployment plan. Only runs if a
        /// "GenerateUpdateReport=true" contributor argument is set in the project file, in a targets file or
        /// passed as an additional argument to the DacServices API. To set in a project file, add:
        ///
        /// <PropertyGroup>
        ///     <ContributorArguments Condition="'$(Configuration)' == 'Debug'">
        /// $(ContributorArguments);DeploymentUpdateReportContributor.GenerateUpdateReport=true;
        ///     </ContributorArguments>
        /// <PropertyGroup>
        ///
        /// </summary>
        [ExportDeploymentPlanExecutor("MyDeploymentContributor.DeploymentUpdateReportContributor", "1.0.0.0")]
        public class DeploymentUpdateReportContributor : DeploymentPlanExecutor
        {
        }
    

    現在您已定義繼承自 DeploymentPlanExecutor 的部署參與者。 在建置和部署流程期間,自訂貢獻者會從標準擴充目錄載入。 部署計劃執行程序參與者是由 ExportDeploymentPlanExecutor 屬性來識別。

    需要這個屬性,才能探索參與者。 它看起來應該類似於以下程式碼:

    [ExportDeploymentPlanExecutor("MyDeploymentContributor.DeploymentUpdateReportContributor", "1.0.0.0")]
    

    在此情況下,屬性的第一個參數應該是唯一識別碼 - 這可用來識別專案檔中的參與者。 最佳做法是將程式庫的命名空間(在本逐步解說中是 MyDeploymentContributor)與類別名稱(在此逐步解說中是 DeploymentUpdateReportContributor)結合,來產生標識符。

  3. 接下來,新增您將使用的下列成員,使此提供者能接受命令列參數:

    public const string GenerateUpdateReport = "DeploymentUpdateReportContributor.GenerateUpdateReport";
    

    這個成員可讓使用者指定是否應該使用 GenerateUpdateReport 選項產生報表。

    接下來,您可以覆寫 OnExecute 方法,以新增您要在部署資料庫項目時執行的程式代碼。

覆寫 OnExecute

  • 將下列方法新增至 DeploymentUpdateReportContributor 類別:

    /// <summary>
            /// Override the OnExecute method to perform actions when you execute the deployment plan for
            /// a database project.
            /// </summary>
            protected override void OnExecute(DeploymentPlanContributorContext context)
            {
                // determine whether the user specified a report is to be generated
                bool generateReport = false;
                string generateReportValue;
                if (context.Arguments.TryGetValue(GenerateUpdateReport, out generateReportValue) == false)
                {
                    // couldn't find the GenerateUpdateReport argument, so do not generate
                    generateReport = false;
                }
                else
                {
                    // GenerateUpdateReport argument was specified, try to parse the value
                    if (bool.TryParse(generateReportValue, out generateReport))
                    {
                        // if we end up here, the value for the argument was not valid.
                        // default is false, so do nothing.
                    }
                }
    
                if (generateReport == false)
                {
                    // if user does not want to generate a report, we are done
                    return;
                }
    
                // We output to the same directory where the deployment script
                // is output or to the current directory
                string reportPrefix = context.Options.TargetDatabaseName;
                string reportPath;
                if (string.IsNullOrEmpty(context.DeploymentScriptPath))
                {
                    reportPath = Environment.CurrentDirectory;
                }
                else
                {
                    reportPath = Path.GetDirectoryName(context.DeploymentScriptPath);
                }
                FileInfo summaryReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".summary.xml"));
                FileInfo detailsReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".details.xml"));
    
                // Generate the reports by using the helper class DeploymentReportWriter
                DeploymentReportWriter writer = new DeploymentReportWriter(context);
                writer.WriteReport(summaryReportFile);
                writer.IncludeScripts = true;
                writer.WriteReport(detailsReportFile);
    
                string msg = "Deployment reports ->"
                    + Environment.NewLine + summaryReportFile.FullName
                    + Environment.NewLine + detailsReportFile.FullName;
    
                ExtensibilityError reportMsg = new ExtensibilityError(msg, Severity.Message);
                base.PublishMessage(reportMsg);
            }
        /// <summary>
        /// Override the OnExecute method to perform actions when you execute the deployment plan for
        /// a database project.
        /// </summary>
            protected override void OnExecute(DeploymentPlanContributorContext context)
            {
                // determine whether the user specified a report is to be generated
                bool generateReport = false;
                string generateReportValue;
                if (context.Arguments.TryGetValue(GenerateUpdateReport, out generateReportValue) == false)
                {
                    // couldn't find the GenerateUpdateReport argument, so do not generate
                    generateReport = false;
                }
                else
                {
                    // GenerateUpdateReport argument was specified, try to parse the value
                    if (bool.TryParse(generateReportValue, out generateReport))
                    {
                        // if we end up here, the value for the argument was not valid.
                        // default is false, so do nothing.
                    }
                }
    
                if (generateReport == false)
                {
                    // if user does not want to generate a report, we are done
                    return;
                }
    
                // We output to the same directory where the deployment script
                // is output or to the current directory
                string reportPrefix = context.Options.TargetDatabaseName;
                string reportPath;
                if (string.IsNullOrEmpty(context.DeploymentScriptPath))
                {
                    reportPath = Environment.CurrentDirectory;
                }
                else
                {
                    reportPath = Path.GetDirectoryName(context.DeploymentScriptPath);
                }
                FileInfo summaryReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".summary.xml"));
                FileInfo detailsReportFile = new FileInfo(Path.Combine(reportPath, reportPrefix + ".details.xml"));
    
                // Generate the reports by using the helper class DeploymentReportWriter
                DeploymentReportWriter writer = new DeploymentReportWriter(context);
                writer.WriteReport(summaryReportFile);
                writer.IncludeScripts = true;
                writer.WriteReport(detailsReportFile);
    
                string msg = "Deployment reports ->"
                    + Environment.NewLine + summaryReportFile.FullName
                    + Environment.NewLine + detailsReportFile.FullName;
    
                DataSchemaError reportMsg = new DataSchemaError(msg, ErrorSeverity.Message);
                base.PublishMessage(reportMsg);
            }
    

    OnExecute 方法會傳遞 DeploymentPlanContributorContext 物件,以存取任何指定的自變數、來源和目標資料庫模型、建置屬性和延伸模組檔案。 在此範例中,我們會取得模型,然後呼叫協助程式函式來輸出模型的相關信息。 我們會在基類上使用 PublishMessage 協助程式方法來報告任何發生的錯誤。

    其他感興趣的類型和方法包括:TSqlModelModelComparisonResultDeploymentPlanHandleSqlDeploymentOptions

    接下來,您會定義協助程序類別,以深入瞭解部署計劃的詳細數據。

新增產生報表本文的協助程式類別

  • 加入下列程式碼,以新增協作類別及其方法:

    /// <summary>
            /// This class is used to generate a deployment
            /// report.
            /// </summary>
            private class DeploymentReportWriter
            {
                readonly TSqlModel _sourceModel;
                readonly ModelComparisonResult _diff;
                readonly DeploymentStep _planHead;
    
                /// <summary>
                /// The constructor accepts the same context info
                /// that was passed to the OnExecute method of the
                /// deployment contributor.
                /// </summary>
                public DeploymentReportWriter(DeploymentPlanContributorContext context)
                {
                    if (context == null)
                    {
                        throw new ArgumentNullException("context");
                    }
    
                    // save the source model, source/target differences,
                    // and the beginning of the deployment plan.
                    _sourceModel = context.Source;
                    _diff = context.ComparisonResult;
                    _planHead = context.PlanHandle.Head;
                }
                /// <summary>
                /// Property indicating whether script bodies
                /// should be included in the report.
                /// </summary>
                public bool IncludeScripts { get; set; }
    
                /// <summary>
                /// Drives the report generation, opening files,
                /// writing the beginning and ending report elements,
                /// and calling helper methods to report on the
                /// plan operations.
                /// </summary>
                internal void WriteReport(FileInfo reportFile)
                {// Assumes that we have a valid report file
                    if (reportFile == null)
                    {
                        throw new ArgumentNullException("reportFile");
                    }
    
                    // set up the XML writer
                    XmlWriterSettings xmlws = new XmlWriterSettings();
                    // Indentation makes it a bit more readable
                    xmlws.Indent = true;
                    FileStream fs = new FileStream(reportFile.FullName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
                    XmlWriter xmlw = XmlWriter.Create(fs, xmlws);
    
                    try
                    {
                        xmlw.WriteStartDocument(true);
                        xmlw.WriteStartElement("DeploymentReport");
    
                        // Summary report of the operations that
                        // are contained in the plan.
                        ReportPlanOperations(xmlw);
    
                        // You could add a method call here
                        // to produce a detailed listing of the
                        // differences between the source and
                        // target model.
                        xmlw.WriteEndElement();
                        xmlw.WriteEndDocument();
                        xmlw.Flush();
                        fs.Flush();
                    }
                    finally
                    {
                        xmlw.Close();
                        fs.Dispose();
                    }
                }
    
                /// <summary>
                /// Writes details for the various operation types
                /// that could be contained in the deployment plan.
                /// Optionally writes script bodies, depending on
                /// the value of the IncludeScripts property.
                /// </summary>
                private void ReportPlanOperations(XmlWriter xmlw)
                {// write the node to indicate the start
                    // of the list of operations.
                    xmlw.WriteStartElement("Operations");
    
                    // Loop through the steps in the plan,
                    // starting at the beginning.
                    DeploymentStep currentStep = _planHead;
                    while (currentStep != null)
                    {
                        // Report the type of step
                        xmlw.WriteStartElement(currentStep.GetType().Name);
    
                        // based on the type of step, report
                        // the relevant information.
                        // Note that this procedure only handles
                        // a subset of all step types.
                        if (currentStep is SqlRenameStep)
                        {
                            SqlRenameStep renameStep = (SqlRenameStep)currentStep;
                            xmlw.WriteAttributeString("OriginalName", renameStep.OldName);
                            xmlw.WriteAttributeString("NewName", renameStep.NewName);
                            xmlw.WriteAttributeString("Category", GetElementCategory(renameStep.RenamedElement));
                        }
                        else if (currentStep is SqlMoveSchemaStep)
                        {
                            SqlMoveSchemaStep moveStep = (SqlMoveSchemaStep)currentStep;
                            xmlw.WriteAttributeString("OriginalName", moveStep.PreviousName);
                            xmlw.WriteAttributeString("NewSchema", moveStep.NewSchema);
                            xmlw.WriteAttributeString("Category", GetElementCategory(moveStep.MovedElement));
                        }
                        else if (currentStep is SqlTableMigrationStep)
                        {
                            SqlTableMigrationStep dmStep = (SqlTableMigrationStep)currentStep;
                            xmlw.WriteAttributeString("Name", GetElementName(dmStep.SourceTable));
                            xmlw.WriteAttributeString("Category", GetElementCategory(dmStep.SourceElement));
                        }
                        else if (currentStep is CreateElementStep)
                        {
                            CreateElementStep createStep = (CreateElementStep)currentStep;
                            xmlw.WriteAttributeString("Name", GetElementName(createStep.SourceElement));
                            xmlw.WriteAttributeString("Category", GetElementCategory(createStep.SourceElement));
                        }
                        else if (currentStep is AlterElementStep)
                        {
                            AlterElementStep alterStep = (AlterElementStep)currentStep;
                            xmlw.WriteAttributeString("Name", GetElementName(alterStep.SourceElement));
                            xmlw.WriteAttributeString("Category", GetElementCategory(alterStep.SourceElement));
                        }
                        else if (currentStep is DropElementStep)
                        {
                            DropElementStep dropStep = (DropElementStep)currentStep;
                            xmlw.WriteAttributeString("Name", GetElementName(dropStep.TargetElement));
                            xmlw.WriteAttributeString("Category", GetElementCategory(dropStep.TargetElement));
                        }
    
                        // If the script bodies are to be included,
                        // add them to the report.
                        if (this.IncludeScripts)
                        {
                            using (StringWriter sw = new StringWriter())
                            {
                                currentStep.GenerateBatchScript(sw);
                                string tsqlBody = sw.ToString();
                                if (string.IsNullOrEmpty(tsqlBody) == false)
                                {
                                    xmlw.WriteCData(tsqlBody);
                                }
                            }
                        }
    
                        // close off the current step
                        xmlw.WriteEndElement();
                        currentStep = currentStep.Next;
                    }
                    xmlw.WriteEndElement();
                }
    
                /// <summary>
                /// Returns the category of the specified element
                /// in the source model
                /// </summary>
                private string GetElementCategory(TSqlObject element)
                {
                    return element.ObjectType.Name;
                }
    
                /// <summary>
                /// Returns the name of the specified element
                /// in the source model
                /// </summary>
                private static string GetElementName(TSqlObject element)
                {
                    StringBuilder name = new StringBuilder();
                    if (element.Name.HasExternalParts)
                    {
                        foreach (string part in element.Name.ExternalParts)
                        {
                            if (name.Length > 0)
                            {
                                name.Append('.');
                            }
                            name.AppendFormat("[{0}]", part);
                        }
                    }
    
                    foreach (string part in element.Name.Parts)
                    {
                        if (name.Length > 0)
                        {
                            name.Append('.');
                        }
                        name.AppendFormat("[{0}]", part);
                    }
    
                    return name.ToString();
                }
            }        /// <summary>
            /// This class is used to generate a deployment
            /// report.
            /// </summary>
            private class DeploymentReportWriter
            {
                /// <summary>
                /// The constructor accepts the same context info
                /// that was passed to the OnExecute method of the
                /// deployment contributor.
                /// </summary>
                public DeploymentReportWriter(DeploymentPlanContributorContext context)
                {
               }
                /// <summary>
                /// Property indicating whether script bodies
                /// should be included in the report.
                /// </summary>
                public bool IncludeScripts { get; set; }
    
                /// <summary>
                /// Drives the report generation, opening files,
                /// writing the beginning and ending report elements,
                /// and calling helper methods to report on the
                /// plan operations.
                /// </summary>
                internal void WriteReport(FileInfo reportFile)
                {
                }
    
                /// <summary>
                /// Writes details for the various operation types
                /// that could be contained in the deployment plan.
                /// Optionally writes script bodies, depending on
                /// the value of the IncludeScripts property.
                /// </summary>
                private void ReportPlanOperations(XmlWriter xmlw)
                {
                }
    
                /// <summary>
                /// Returns the category of the specified element
                /// in the source model
                /// </summary>
                private string GetElementCategory(IModelElement element)
                {
                }
    
                /// <summary>
                /// Returns the name of the specified element
                /// in the source model
                /// </summary>
                private string GetElementName(IModelElement element)
                {
                }
            }
    
  • 將變更儲存至類別檔案。 助手類別中參考了幾個有用的類型:

    代碼區 有用的類型
    類別成員 TSqlModelModelComparisonResultDeploymentStep
    WriteReport 方法 XmlWriter 和 XmlWriterSettings
    ReportPlanOperations 方法 感興趣的類型包括: DeploymentStepSqlRenameStepSqlMoveSchemaStepSqlTableMigrationStepCreateElementStepAlterElementStepDropElementStep

    還有其他幾個步驟 - 請參閱 API 文件以取得完整的步驟清單。
    取得元素類別 TSqlObject
    GetElementName TSqlObject

    接下來,您會建置類別庫。

簽署並建置組件

  1. 專案 功能表上,選取 MyDeploymentContributor 屬性

  2. 選取 [ 簽署 ] 索引標籤。

  3. 選取 [簽署組件]。

  4. 選擇強式名稱金鑰檔案 中,選取 <新增>

  5. 在「 建立強式名稱索引鍵 」對話方塊中,在 索引鍵檔案名稱中,輸入 MyRefKey

  6. (選擇性)您可以指定強名稱金鑰檔案的密碼。

  7. 請選擇 [確定]

  8. 在 [File] \(檔案\) 功能表上,選取 [Save All] \(全部儲存\)

  9. 在 [建置] 功能表上,選取 [建置方案]

接下來,您必須安裝元件,以確保在建置和部署 SQL 專案時能夠順利載入。

安裝部署參與者

若要安裝部署參與者,您必須將元件和相關的 .pdb 檔案複製到擴充套件資料夾。

安裝 MyDeploymentContributor 程序集

  • 接下來,您將組合資訊複製到 Extensions 目錄。 當 Visual Studio 啟動時,它會識別目錄和子目錄中 %ProgramFiles%\Microsoft SQL Server\110\DAC\Bin\Extensions 的任何延伸模組,並讓它們可供使用:

  • MyDeploymentContributor.dll將組件檔案從輸出目錄複製到目錄%ProgramFiles%\Microsoft SQL Server\110\DAC\Bin\Extensions。 依預設,編譯檔案 .dll 的路徑是 YourSolutionPath\YourProjectPath\bin\DebugYourSolutionPath\YourProjectPath\bin\Release

驗證您的部署貢獻者

若要測試部署參與者,您必須執行下列工作:

  • 將屬性新增至您計劃部署的 .sqlproj 檔案。

  • 使用 MSBuild 部署專案並提供適當的參數。

將屬性新增至 SQL 專案 (.sqlproj) 檔案

您必須一律更新 SQL 項目檔,以指定您想要執行的參與者識別碼。 此外,由於此參與者預期 "GenerateUpdateReport" 引數,因此必須將其指定為參與者的引數。

您可以使用下列兩種方式之一來執行此動作。 您可以手動修改 .sqlproj 檔案以新增所需的引數。 如果您的參與者沒有任何設定所需的參與者引數,或者您不打算在大量專案中重複使用參與者,您可以選擇執行此動作。 如果您選擇此選項,請在檔案中第一個 [匯入] 節點之後將下列陳述式 .sqlproj 新增至檔案:

<PropertyGroup>
    <DeploymentContributors>$(DeploymentContributors); MyDeploymentContributor.DeploymentUpdateReportContributor</DeploymentContributors>
<ContributorArguments Condition="'$(Configuration)' == 'Debug'">$(ContributorArguments);DeploymentUpdateReportContributor.GenerateUpdateReport=true;</ContributorArguments>
  </PropertyGroup>

第二種方法是建立包含必要參與者自變數的目標檔案。 如果您對多個專案使用相同的貢獻者,並且需要貢獻者引數,這很有用,因為它包含預設值。 在此情況下,請在 MSBuild 延伸模組路徑中建立目標檔案。

  1. 導航至 %ProgramFiles%\MSBuild

  2. 建立一個新資料夾 MyContributors 來儲存目標檔案。

  3. 在此目錄中建立一個新文件 MyContributors.targets ,將以下文字新增至其中並儲存該檔案:

    <?xml version="1.0" encoding="utf-8"?>
    
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
    <DeploymentContributors>$(DeploymentContributors);MyDeploymentContributor.DeploymentUpdateReportContributor</DeploymentContributors>
    <ContributorArguments Condition="'$(Configuration)' == 'Debug'">$(ContributorArguments); DeploymentUpdateReportContributor.GenerateUpdateReport=true;</ContributorArguments>
      </PropertyGroup>
    </Project>
    
  4. 在您要執行任何包含貢獻者的專案的 .sqlproj 檔案中,將下列陳述式新增到 .sqlproj 檔案中、位於 <Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets" /> 節點之後,以匯入目標檔案:

    <Import Project="$(MSBuildExtensionsPath)\MyContributors\MyContributors.targets " />
    

遵循下列其中一種方法之後,您可以使用 MSBuild 來傳入命令行組建的參數。

注意

您必須一律更新 「DeploymentContributors」 屬性,以指定參與者標識碼。 這與您參與者來源檔案中的 「ExportDeploymentPlanExecutor」 屬性中使用的標識符相同。 如果沒有這個,您的貢獻者在建置專案時就不會執行。 只有在您的參與者需要執行所需的參數時,才需要更新「ContributorArguments」屬性。

部署資料庫專案

您的專案可以在Visual Studio內以正常方式發佈或部署。 開啟解決方案中的 SQL 專案,在專案上右鍵選單中選擇「發行...」選項,或按 F5 進行偵錯部署至 LocalDB。 在此範例中,我們使用「Publish...」對話方塊以產生部署指令碼。

部署 SQL 專案並產生部署報告

  1. 開啟 Visual Studio,然後開啟包含 SQL 項目的解決方案。

  2. 選取您的專案並按 「F5」 以執行偵錯部署。 注意:由於 ContributorArguments 元素設定為只有在組態為 「偵錯」時才會包含,因此目前只會針對偵錯部署產生部署報告。 若要變更此值,請從 ContributorArguments 定義中移除 Condition=“'$(Configuration)' == 'Debug'” 語句。

  3. 輸出視窗中應該會出現下列範例的輸出:

    ------ Deploy started: Project: Database1, Configuration: Debug Any CPU ------
    Finished verifying cached model in 00:00:00
    Deployment reports ->
    
      C:\Users\UserName\Documents\Visual Studio 2012\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyTargetDatabase.summary.xml
      C:\Users\UserName\Documents\Visual Studio 2012\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyTargetDatabase.details.xml
    
      Deployment script generated to:
      C:\Users\UserName\Documents\Visual Studio 2012\Projects\MyDatabaseProject\MyDatabaseProject\sql\debug\MyDatabaseProject.sql
    
  4. 開啟 MyTargetDatabase.summary.xml 並檢查內容。 檔案類似下列範例,顯示新的資料庫部署:

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <DeploymentReport>
      <Operations>
        <DeploymentScriptStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptStep />
        <DeploymentScriptStep />
        <DeploymentScriptStep />
        <DeploymentScriptStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptStep />
        <DeploymentScriptDomStep />
        <BeginPreDeploymentScriptStep />
        <DeploymentScriptStep />
        <EndPreDeploymentScriptStep />
        <SqlBeginPreservationStep />
        <SqlEndPreservationStep />
        <SqlBeginDropsStep />
        <SqlEndDropsStep />
        <SqlBeginAltersStep />
        <SqlPrintStep />
        <CreateElementStep Name="Sales" Category="Schema" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.Customer" Category="Table" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.PK_Customer_CustID" Category="Primary Key" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.Orders" Category="Table" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.PK_Orders_OrderID" Category="Primary Key" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.Def_Customer_YTDOrders" Category="Default Constraint" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.Def_Customer_YTDSales" Category="Default Constraint" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.Def_Orders_OrderDate" Category="Default Constraint" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.Def_Orders_Status" Category="Default Constraint" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.FK_Orders_Customer_CustID" Category="Foreign Key" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.CK_Orders_FilledDate" Category="Check Constraint" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.CK_Orders_OrderDate" Category="Check Constraint" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.uspCancelOrder" Category="Procedure" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.uspFillOrder" Category="Procedure" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.uspNewCustomer" Category="Procedure" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.uspPlaceNewOrder" Category="Procedure" />
        <SqlPrintStep />
        <CreateElementStep Name="Sales.uspShowOrderDetails" Category="Procedure" />
        <SqlEndAltersStep />
        <DeploymentScriptStep />
        <BeginPostDeploymentScriptStep />
        <DeploymentScriptStep />
        <EndPostDeploymentScriptStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptDomStep />
        <DeploymentScriptDomStep />
      </Operations>
    </DeploymentReport>
    

    注意

    如果您部署與目標資料庫相同的資料庫專案,則產生的報告不是很有意義。 如需更有意義的結果,請將變更部署至資料庫或部署新的資料庫。

  5. 開啟 MyTargetDatabase.details.xml 並檢查內容。 整個詳細資料檔案的一個小段會顯示用於建立 Sales 架構的條目和腳本,列印出關於創建數據表的訊息,以及創建數據表的過程。

    <CreateElementStep Name="Sales" Category="Schema"><![CDATA[CREATE SCHEMA [Sales]
        AUTHORIZATION [dbo];
    
    ]]></CreateElementStep>
        <SqlPrintStep><![CDATA[PRINT N'Creating [Sales].[Customer]...';
    
    ]]></SqlPrintStep>
        <CreateElementStep Name="Sales.Customer" Category="Table"><![CDATA[CREATE TABLE [Sales].[Customer] (
        [CustomerID]   INT           IDENTITY (1, 1) NOT NULL,
        [CustomerName] NVARCHAR (40) NOT NULL,
        [YTDOrders]    INT           NOT NULL,
        [YTDSales]     INT           NOT NULL
    );
    
    ]]></CreateElementStep>
    

    藉由在執行部署計劃時分析部署計劃,您可以報告部署中包含的任何資訊,並可以根據該計劃中的步驟採取更多動作。