VS2010 数据库项目部署——“SqlDeployTask”任务意外失败,NullReferenceException

Posted

技术标签:

【中文标题】VS2010 数据库项目部署——“SqlDeployTask”任务意外失败,NullReferenceException【英文标题】:VS2010 Database project deploy - "SqlDeployTask" task failed unexpectedly, NullReferenceException 【发布时间】:2011-10-04 14:38:52 【问题描述】:

我在 Visual Studio 2010 中有一个解决方案,其中包含许多 SQL Server 2008 数据库项目。我正在尝试执行“部署解决方案”,但其中一个数据库项目出现以下错误:

------ Deploy started: Project: MyDBProj, Configuration: Sandbox Any CPU ------
C:\Program Files\MSBuild\Microsoft\VisualStudio\v10.0\TeamData\Microsoft.Data.Schema.TSqlTasks.targets(120,5): Error MSB4018: The "SqlDeployTask" task failed unexpectedly.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Data.Schema.Sql.SchemaModel.SqlModelComparerBase.VariableSubstitution(SqlScriptProperty propertyValue, IDictionary`2 variables, Boolean& isChanged)
   at Microsoft.Data.Schema.Sql.SchemaModel.SqlModelComparerBase.ArePropertiesEqual(IModelElement source, IModelElement target, ModelPropertyClass propertyClass, ModelComparerConfiguration configuration)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareProperties(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, ModelComparisonChangeDefinition changes)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareElementsWithoutCompareName(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, Boolean parentExplicitlyIncluded, Boolean compareElementOnly, ModelComparisonResult result, ModelComparisonChangeDefinition changes)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareElementsWithSameType(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, ModelComparisonResult result, Boolean ignoreComparingName, Boolean parentExplicitlyIncluded, Boolean compareElementOnly, Boolean compareFromRootElement, ModelComparisonChangeDefinition& changes)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareChildren(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, Boolean parentExplicitlyIncluded, Boolean compareParentElementOnly, ModelComparisonResult result, ModelComparisonChangeDefinition changes, Boolean isComposing)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareElementsWithoutCompareName(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, Boolean parentExplicitlyIncluded, Boolean compareElementOnly, ModelComparisonResult result, ModelComparisonChangeDefinition changes)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareElementsWithSameType(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, ModelComparisonResult result, Boolean ignoreComparingName, Boolean parentExplicitlyIncluded, Boolean compareElementOnly, Boolean compareFromRootElement, ModelComparisonChangeDefinition& changes)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareChildren(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, Boolean parentExplicitlyIncluded, Boolean compareParentElementOnly, ModelComparisonResult result, ModelComparisonChangeDefinition changes, Boolean isComposing)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareElementsWithoutCompareName(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, Boolean parentExplicitlyIncluded, Boolean compareElementOnly, ModelComparisonResult result, ModelComparisonChangeDefinition changes)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareElementsWithSameType(IModelElement sourceElement, IModelElement targetElement, ModelComparerConfiguration configuration, ModelComparisonResult result, Boolean ignoreComparingName, Boolean parentExplicitlyIncluded, Boolean compareElementOnly, Boolean compareFromRootElement, ModelComparisonChangeDefinition& changes)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareAllElementsForOneType(ModelElementClass type, ModelComparerConfiguration configuration, ModelComparisonResult result, Boolean compareOrphanedElements)
   at Microsoft.Data.Schema.SchemaModel.ModelComparer.CompareStore(ModelStore source, ModelStore target, ModelComparerConfiguration configuration)
   at Microsoft.Data.Schema.Build.SchemaDeployment.CompareModels()
   at Microsoft.Data.Schema.Build.SchemaDeployment.PrepareBuildPlan()
   at Microsoft.Data.Schema.Build.SchemaDeployment.Execute(Boolean executeDeployment)
   at Microsoft.Data.Schema.Build.SchemaDeployment.Execute()
   at Microsoft.Data.Schema.Tasks.DBDeployTask.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(ITaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask, Boolean& taskResult)
   Done executing task "SqlDeployTask" -- FAILED.
  Done building target "DspDeploy" in project "MyDBProj.dbproj" -- FAILED.
 Done executing task "CallTarget" -- FAILED.
Done building target "DBDeploy" in project "MyDBProj.dbproj" -- FAILED.
Done building project "MyDBProj.dbproj" -- FAILED.

有人知道是什么原因造成的吗?

我的项目配置为创建部署脚本并针对目标数据库运行它。 在运行部署之前,我尝试删除目标数据库并创建一个空数据库。 我已经尝试在 Visual Studio 中“清理”解决方案。

【问题讨论】:

【参考方案1】:

汤姆, 我在这里记录了一种解决方法(并且非常简单):http://sqlblog.com/blogs/jamie_thomson/archive/2011/11/21/workaround-for-datadude-deployment-bug.aspx

【讨论】:

【参考方案2】:

当遇到以下情况时,我遇到了下面附加的类似 NullReference 异常:

    我已经编辑了 SQL 数据库项目的分区方案 PS1 的定义以及使用它的所有表(T1、T2、T3) 但是,在我的数据库中,我有一个未在代码中定义的旧表 (T_old),但仍未从数据库中删除(它不再使用,但 dacpac 不会为您删除内容,只会更改或添加)。这个旧表使用相同的分区方案,但 dacpac 没有引用旧表定义,这意味着它无法备份表 T_old 以更改 PS1

当引用由不再在代码中定义的旧对象更改的对象时,您可能会遇到类似的问题。

要解决这个问题,请检查对象的旧依赖项并将其删除。尝试仅在代码中进行更改,不要将其与数据库中的临时更改混为一谈。

希望这会有所帮助,因为错误消息没有给出太多解释。

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
    at Microsoft.Data.Tools.Schema.Sql.Deployment.SqlDeploymentPlanGenerator.DeploymentScriptDomGenerator.UnbindTableDatamotion(SqlTable sourceTable, SqlTable targetTable, Boolean unbindPartitionScheme, HashSet`1 unboundColumns)
    at Microsoft.Data.Tools.Schema.Sql.Deployment.SqlDeploymentPlanGenerator.DeploymentScriptDomGenerator.GenerateUnbindTableSteps(SqlTable sourceTable, SqlTable targetTable)
    at Microsoft.Data.Tools.Schema.Sql.Deployment.SqlDeploymentPlanGenerator.DeploymentScriptDomGenerator.GenerateSteps(Int32 operation, IModelElement element)
...

【讨论】:

我在使用 Azure DevOps 管道发布数据库 dacpac 时遇到了同样的 UnbindTableDatamotion 错误。不幸的是,在 pre-prod 版本和 prod 版本之间,一位同事在生产环境中的数据库中添加了一些分区,但此更改尚未合并到我的 SQL 项目中。我们没有意识到这会导致冲突!【参考方案3】:

我已经能够使用包含单个内联函数的测试数据库项目重现此错误,如下所示:

CREATE FUNCTION [dbo].[Function1]
()
RETURNS TABLE
AS
    RETURN (
        WITH cte AS (
            SELECT 1 AS [c1]
            FROM [$(Database3)].[dbo].[Table1]
        )
        SELECT 1 AS [c1]
        FROM cte
    )

$(Database3) 是引用另一个数据库项目.dbschema 文件的数据库变量。此 dbschema 文件包含一个表 - [Table1]

您似乎需要一个带有 CTE 的内联函数,该函数包含使用数据库变量对另一个数据库的引用。此外,该函数必须已经存在于目标数据库中。

在某些情况下您可能会收到以下错误(例如,内联函数不使用 CTE):

------ Deploy started: Project: Database2, Configuration: Debug Any CPU ------
Database2.dbschema(0,0): Warning TSD00560: If this deployment is executed, changes to [dbo].[Function2] might introduce run-time errors in [dbo].[Procedure1].
    Deployment script generated to:
C:\temp\Database2\sql\debug\Database2.sql

    Altering [dbo].[Function2]...
C:\temp\Database2\sql\debug\Database2.sql(74,0): Error SQL01268: .Net SqlClient Data Provider: Msg 208, Level 16, State 1, Procedure Function2, Line 9 Invalid object name 'Database3.dbo.Table1'.
    An error occurred while the batch was being executed.
   Done executing task "SqlDeployTask" -- FAILED.
  Done building target "DspDeploy" in project "Database2.dbproj" -- FAILED.
 Done executing task "CallTarget" -- FAILED.
Done building target "DBDeploy" in project "Database2.dbproj" -- FAILED.
Done building project "Database2.dbproj" -- FAILED.

Build FAILED.

因此,唯一的解决方法似乎是在部署之前将函数放在目标中。

我将提出 Microsoft Connect 问题。

更新

我创建了一个 Connect 问题 - https://connect.microsoft.com/VisualStudio/feedback/details/693158/vs2010-database-project-deploy-sqldeploytask-task-failed-unexpectedly-nullreferenceexception

【讨论】:

以上是关于VS2010 数据库项目部署——“SqlDeployTask”任务意外失败,NullReferenceException的主要内容,如果未能解决你的问题,请参考以下文章

VS2010 数据库项目部署——“SqlDeployTask”任务意外失败,NullReferenceException

让 MSBuild 和 CruiseControl .NET 构建和部署 VS2010 数据库项目

在 vs2010 中使用 Database 项目部署和应用发布补丁

VS2010 数据库项目部署,如果可能发生数据丢失会失败吗?

在 VS2010 数据库项目中部署时设置 DefaultDataPath 和 DefaultLogPath

我可以从 TFS CI Build 更改 VS2010 数据库项目的部署脚本的位置吗