是否可以在 T-SQL 中以完全限定的 table 名称有条件地指定数据库?
Is it possible to conditionally specify the database in a fully qualified table name in T-SQL?
在工作中,我们有三个 SQL Server 2008 R2 数据库环境:生产、测试和开发。
在生产环境中,我们系统的不同部分 运行 在 3 个不同的数据库服务器上(我们称它们为 PROD1
、PROD2
和 PROD3
),而在我们在同一台服务器上拥有所有数据库 运行ning 的开发环境(我们称之为 DEV1
)。
这通常不是问题,因为我们的大多数 SQL 代码不需要引用其自身数据库之外的对象。但在少数情况下,视图或存储过程需要引用 table、视图或函数,这些视图或函数不仅驻留在另一个数据库中,而且还驻留在不同生产服务器上的数据库中。 IE。我们在 PROD3
上有一个视图,需要在 PROD1
的用户列表中查找用户,如下所示:
PROD1.UserDB.UserSchema.UserList
当然这给我们的测试环境带来了问题,因为我们需要这些views/stored程序来引用不同的服务器,这取决于它们运行.
我的问题:是否可以在 T-SQL 中的完全限定 table 名称 (ServerName.DatabaseName.SchemaName.TableName
) 中包含条件值? IE。我可以在视图或存储过程中使用类似 (PROD1|DEV1).UserDB.UserSchema.UserList
的东西吗?或者以某种方式从变量中获取服务器名称,然后我们可以根据当前服务器进行设置?
额外问题:在一种情况下,我们甚至还必须更改数据库名称。这可以用类似的方式完成吗?
我意识到我们可以通过在字符串中创建动态 SQL 语句然后执行它来解决这个问题。但出于各种原因,我们非常希望避免这种方法。
对于跨数据库引用,您最好的选择可能是使用 synonyms。 DEV 和 PROD 的同义词定义会有所不同,但使用同义词的复杂对象(视图、SP 等)的定义可以保持不变。
您想要 Linked Servers and server aliases.
的组合
如前所述,您确实需要使用动态 SQL。但是您可以使用它来创建对象:只需在动态 SQL 中为需要从另一台服务器和/或另一台数据库访问的所有对象创建同义词。
在这种情况下,您的所有代码都将是静态的,并且仅在使用动态 SQL 的安装/部署过程中才会引用所需的对象。
代码可以像下面这样:
declare @sql nvarchar(max)
if @@servername = 'DEV1'
set @sql = 'create synonym vUserList for [Dev1].UserDB.UserSchema.UserList'
else
set @sql = 'create synonym vUserList for [PROD1].UserDB.UserSchema.UserList'
exec sp_executesql @sql
并且您的所有代码(SP、函数等)都可以使用这个同义词 - vUserList
您可以以相同的方式更改目标数据库名称,具体取决于环境 - test、dev 或 prod
在工作中,我们有三个 SQL Server 2008 R2 数据库环境:生产、测试和开发。
在生产环境中,我们系统的不同部分 运行 在 3 个不同的数据库服务器上(我们称它们为 PROD1
、PROD2
和 PROD3
),而在我们在同一台服务器上拥有所有数据库 运行ning 的开发环境(我们称之为 DEV1
)。
这通常不是问题,因为我们的大多数 SQL 代码不需要引用其自身数据库之外的对象。但在少数情况下,视图或存储过程需要引用 table、视图或函数,这些视图或函数不仅驻留在另一个数据库中,而且还驻留在不同生产服务器上的数据库中。 IE。我们在 PROD3
上有一个视图,需要在 PROD1
的用户列表中查找用户,如下所示:
PROD1.UserDB.UserSchema.UserList
当然这给我们的测试环境带来了问题,因为我们需要这些views/stored程序来引用不同的服务器,这取决于它们运行.
我的问题:是否可以在 T-SQL 中的完全限定 table 名称 (ServerName.DatabaseName.SchemaName.TableName
) 中包含条件值? IE。我可以在视图或存储过程中使用类似 (PROD1|DEV1).UserDB.UserSchema.UserList
的东西吗?或者以某种方式从变量中获取服务器名称,然后我们可以根据当前服务器进行设置?
额外问题:在一种情况下,我们甚至还必须更改数据库名称。这可以用类似的方式完成吗?
我意识到我们可以通过在字符串中创建动态 SQL 语句然后执行它来解决这个问题。但出于各种原因,我们非常希望避免这种方法。
对于跨数据库引用,您最好的选择可能是使用 synonyms。 DEV 和 PROD 的同义词定义会有所不同,但使用同义词的复杂对象(视图、SP 等)的定义可以保持不变。
您想要 Linked Servers and server aliases.
的组合如前所述,您确实需要使用动态 SQL。但是您可以使用它来创建对象:只需在动态 SQL 中为需要从另一台服务器和/或另一台数据库访问的所有对象创建同义词。
在这种情况下,您的所有代码都将是静态的,并且仅在使用动态 SQL 的安装/部署过程中才会引用所需的对象。
代码可以像下面这样:
declare @sql nvarchar(max)
if @@servername = 'DEV1'
set @sql = 'create synonym vUserList for [Dev1].UserDB.UserSchema.UserList'
else
set @sql = 'create synonym vUserList for [PROD1].UserDB.UserSchema.UserList'
exec sp_executesql @sql
并且您的所有代码(SP、函数等)都可以使用这个同义词 - vUserList
您可以以相同的方式更改目标数据库名称,具体取决于环境 - test、dev 或 prod