【发布时间】:2012-07-16 15:15:28
【问题描述】:
我们有一个通过 TFS、TFS 数据库项目和 vsdbcmd 的自动化构建过程。将数据库项目部署到我们的数据库服务器时,生成的 SQL 脚本会尝试“更改”某些存储过程,即使目标数据库中尚不存在这些存储过程。相反,SQL 脚本应该包含那些存储过程的“CREATE”语句。这显然会导致数据库部署失败,因为无法“更改”不存在的存储过程。
是否有人对可能导致此问题的原因或如何解决此问题有任何想法?
【问题讨论】:
我们有一个通过 TFS、TFS 数据库项目和 vsdbcmd 的自动化构建过程。将数据库项目部署到我们的数据库服务器时,生成的 SQL 脚本会尝试“更改”某些存储过程,即使目标数据库中尚不存在这些存储过程。相反,SQL 脚本应该包含那些存储过程的“CREATE”语句。这显然会导致数据库部署失败,因为无法“更改”不存在的存储过程。
是否有人对可能导致此问题的原因或如何解决此问题有任何想法?
【问题讨论】:
您是否使用 VSDBCMD 部署到目标数据库? VSDBCMD 应将 .dbschema 文件和连接字符串作为输入,并生成适当的 SQL 文件。如果您在指向不同 DB 时生成 SQL 文件,那么它将无法在处于不同状态的 DB 服务器上运行。
【讨论】:
我们在 TFS 构建中使用了类似的过程,我很确定这会成功处理新插入的元素(表、列、SP、索引等)。
首先,我们通过调用 VSDBCMD 生成旧数据库的 .dbschema:
/a:import /dsp:sql /model:C:\PATH\old.dbschema /cs:"Server=SQLSERVER;Integrated Security=False;Pooling=False;Initial Catalog=OLDDB;User=username;Password=password;
然后我们生成数据库最新状态的 .dbschema,该数据库在较早的步骤中已部署(通过 MSBuild):
/a:import /dsp:sql /model:C:\PATH\new.dbschema /cs:"Server=SQLSERVER;Integrated Security=False;Pooling=False;Initial Catalog=NEWDB;User=username;Password=password;
我们最后第三次调用 VSDBCMD,以便它生成 ALTER:
/a:deploy /dsp:sql /model:C:\PATH\new.dbschema /targetmodelfile:C:\PATH\old.dbschema /DeploymentScriptFile:C:\PATH\DB_Alter.sql /p:Targetdatabase="DB"
这个生成的 DB_Alter.sql 可以应用于运行数据库先前状态的生产 SQL,以便将其塑造成最新状态。
您的暗示可以追溯到您没有正确形成 VSDBCMD 参数,或者是工具的直接错误。在您的位置,我会手动尝试使用该工具,以确保两者中的哪一个适用。
据我所知,上述过程可以正常工作,因此我倾向于认为您的实施存在问题。
【讨论】:
找出问题所在: 在 TFS 中,表定义没有架构前缀。所以而不是(例如)
CREATE TABLE [dbo][TableName]
原来是
CREATE TABLE [TableName]
未指定架构意味着当 QA 运行 vsdbcmd 时,分配给表的架构是运行 vsdbcmd 的个人的默认架构。所以实际创建的是有效地,就好像我们已经指定了:
CREATE TABLE [QAUser_SCHEMA].[TableName]
这导致 vsdbcmd,稍后由默认架构为 [dbo] 的另一个人运行时收到我们看到的错误,基本上生成一个 ALTER 语句,因为存储过程已经创建,尽管在不同的架构下。
人们会认为,即使最初指定的模式不正确,一旦为过程指定了 [dbo] 模式,它就会被视为“不同”的过程,但事实并非如此。删除过程的原始版本(带有 [QAUser_SCHEMA] 的那个),然后重新运行 vsdbcmd 解决了问题。
TLDR; 始终在数据库项目中为数据库对象添加架构名称前缀。
【讨论】: