如何制作';模式比较';数据库管理->;SQL项目尊重SQL-CMD变量
我有一个VisualStudio2013解决方案,包含2个SQL项目DB1和DB2 DB1有一个引用DB2的存储过程 如果我在过程中使用.dacpac和同义词如何制作';模式比较';数据库管理->;SQL项目尊重SQL-CMD变量,sql,visual-studio-2013,schema,database-project,schema-compare,Sql,Visual Studio 2013,Schema,Database Project,Schema Compare,我有一个VisualStudio2013解决方案,包含2个SQL项目DB1和DB2 DB1有一个引用DB2的存储过程 如果我在过程中使用.dacpac和同义词 SELECT * FROM [$(DB2)].[dbo].[Table1] 然后,将数据库中的模式与SQL项目进行比较错误地将上述内容检测为更改,因为它不处理变量/同义词 如果我用 SELECT * FROM DB2.[dbo].[Table1] 并将存储过程生成类型更改为None(以便项目生成),然后模式比较从数据库转到项目时**将
SELECT * FROM [$(DB2)].[dbo].[Table1]
然后,将数据库中的模式与SQL项目进行比较错误地将上述内容检测为更改,因为它不处理变量/同义词
如果我用
SELECT * FROM DB2.[dbo].[Table1]
并将存储过程生成类型更改为None(以便项目生成),然后模式比较从数据库转到项目时**将“看不到”项目中的存储过程,并在每次比较时向SQL数据库项目添加新的过程
在模式比较之后,我现在将看到
- DB1
- dbo
- 存储过程
- sp_myStoredProcedure.sql
- sp_myStoredProcedure1.sql
- sp_myStoredProceduren.sql
- 存储过程
- dbo
SELECT * FROM DB1.dbo.Table1 T1
INNER JOIN DB2.dbo.Table2 T2
ON T2.Field1 = T1.Field1
在您的DB1SQL项目中,是原始的(没有自引用DB1)
模式比较将无法正确替换变量并识别更改:[$(DB2)]->$(DB2)
问题是自引用DB1.dbo.Table,在我的例子中,它被插入了大量连接的一半,其中许多是DB2引用
这会导致SC错误地将所有[$(DB2)]标记为更改。可能是因为数据库sql没有在VS中“生成”并还原为文本比较
所以这并不是一个真正的bug,但对于并没有手动比较每一行SQL的开发人员来说,这是一个令人困惑的结果
我认为这个问题可以扩展到以下方面:
任何时候数据库SQL不构建SQL CMD变量都不会
已解析,并将导致可能模糊原始生成的错误
失败
我还必须补充一点,在我的例子中,DB2也引用DB1
这可能是未能正确报告错误的部分原因
最后,为了避免循环依赖(项目不能相互引用),我使用项目引用构建了引用DB2的DB1,但检查了“superss build errors In the referenced Project”。DB2没有构建,因为它引用了DB1
一旦构建了DB1,我就使用bin文件夹中的输出DACPAC,将其复制到另一个位置,并在DB2中引用该db1dacpac。现在,每当DB1发生更改时,我都必须将DACPAC复制到此文件夹。幸运的是,这不会改变太多
整个过程非常复杂,SQL项目应该允许相互引用(使用远程错误抑制),但不管怎样,最终我还是设法得到了2个db,它们将相互引用,并且所有这些都与同义词和模式比较兼容
只花了两天的时间
可以通过更改数据库项目属性中的SQLCMD变量默认值或本地设置来避免此问题。这种行为是: -如果定义了一个局部值,这就是在模式比较中使用的值 -如果未定义局部值,则将使用默认值。 因此,更新本地值以匹配引用的数据库名称、重建和执行新的模式比较应该可以解决这一问题 如果有多个数据库要作为目标,那么现在最好的选择是根据您的配置为“本地”值设置不同的值。这意味着:
调试
释放
正如您所看到的,这意味着在调试配置中,它将有一个不同的值来释放。在现实世界中,您可能会为目标服务器创建一个配置
这比理想情况下更麻烦,但它确实解决了您的问题,并且是在现有工具的情况下这样做的最佳方式
更新:要解决数据库项目之间存在循环依赖关系的潜在问题,应使用复合项目。基本过程是:
- 创建“DB1_核心”和“DB2_核心”项目。将其他数据库引用的对象放在核心项目中
- 在DB1项目中,添加“DB1_Core”作为“相同的数据库”引用。这将确保在使用“Include Composite Objects=true”发布时,DB1项目会像以前一样发布—所有核心对象都将被包括在内
- 对DB2项目执行同样的操作
- DB1应该只需要对DB2_核心的引用,DB2引用DB1_核心。这打破了循环依赖关系,允许您安全地构建
这是一种最佳实践,遵循与C#和其他项目类型类似的模式。有一个关于复合项目的演示-链接在.Kevin上,因为我怀疑这不起作用。也许
SELECT * FROM dbo.Table1 T1
INNER JOIN [$(DB2)].dbo.Table2 T2
ON T2.Field1 = T1.Field1
<SqlCmdVar__1 Condition=" '$(Configuration)' == 'Debug' ">Debug</SqlCmdVar__1>
<SqlCmdVar__1 Condition=" '$(Configuration)' == 'Release' ">Release</SqlCmdVar__1>