跨数据库SQL脚本

3

我正在处理一个项目,其中我们直接从一个数据库通信到另一个数据库。我们有一个主数据库,客户可以在其中更新其网站,然后通过多个SQL脚本将更改从一个数据库推送到另一个数据库。主数据库作为预览站点,允许他们在将更改推送到生产环境之前查看更改。

目前,我们将从库数据库名称直接编码到SQL查询中。

例如:INSERT INTO [slave-database].dbo.TableName

然而,在开发中分支出多组两个数据库时,这是绝对痛苦的。与正在进行的开发相关的任何存储过程都会被更新以指向该特定分支的从库数据库,例如[branch5-slave-database]。

这不是理想的解决方案,因为当推入主干时必须手动调整更改(替换硬编码的数据库名称)。

有更好的方法吗?目前我唯一能看到的解决方案是为每个分支创建一个SQL Server实例,这意味着所有分支的数据库名称始终可以保持相同。但这将是绝对痛苦的,并且会有相当大的开销。是否可以在SQL Server中设置数据库名称的常量?这样我们就可以只更新分支数据库上的单个值。动态SQL是行不通的。


我找到的最佳选项是SQL Server 2005的同义词。它们不能在数据库级别使用,因此我为每个在数据库之间引用的对象创建了一个同义词。然后,我将编写一个脚本,可以快速重新构建具有不同数据库名称的同义词。 - Craig Bovis
4个回答

1

看一下如何使用未记录的系统存储过程sp_MSforeachdb

sp_MSforeachdb

它允许您针对当前实例中的每个数据库处理代码。如果需要,您可以明确排除系统数据库。


0

您可以使用动态SQL更改从数据库的名称。例如:

declare @query nvarchar(4000)
set @query = 'INSERT INTO [' + @slavedbname + '].dbo.TableName ...'
exec sp_executesql @query

您可以将从数据库的名称存储在一个表中,并从那里检索它:
select @slavedbname = value from Settings where name = 'SlaveDbName'

或者你可以约定它等于当前数据库加上_slave:

select @slavedbname = db_name() + '_slave'

0

在使用动态生成的Sql(如@Andomar所建议的)时,没有办法在SQL中(运行时)参数化数据库名称。

然而,在执行DDL以构建数据库时,您有更多选项。可能最简单的方法是使用SQLCmd参数语法,在执行构建脚本时提供从属数据库名称作为参数(请参见SQLCmd doco)。这可以并入您的构建/部署脚本中,因此,为给定环境进行模式构建可以轻松自动化。我曾经为您描述的情况几乎完全采用这种方式。

最终的最佳答案可能是将内容迁移彻底从数据库中删除,并将其放入应用程序层。这通常是一种更干净的方法,并带来了额外的好处,因为两个数据库的位置不再重要(它们可以位于不同的服务器上,例如)。只有您才能决定这是否过度强调了您的需求。


0

一些DBMS方言允许在连接时使用数据库别名打开数据库。这使您可以获得SQL其他部分中表别名或列别名所具有的某些灵活性。

在这种情况下,您可以使用“slave”数据库别名发出连接,无论实际连接字符串是什么。然后,您就不必在查询中编写实际的从数据库名称。但是,您必须管理连续打开和关闭各个从服务器,以避免“slave”名称冲突。

另一种选择是使用表链接(如果您的方言支持)。您将面临类似的问题,需要避免冲突。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接