我有两个不同的SQL Server数据库(在同一台服务器上 - 如果它有帮助)需要共享相同的存储过程逻辑。我想要实现的解决方案如下:
Database1
Table: TestTable
Synonym: sp_MyProc pointing at SharedDatabase.dbo.sp_MyProc
Database2
Table: TestTable
Synonym: sp_MyProc pointing at SharedDatabase.dbo.sp_MyProc
SharedDatabase
Proc: sp_MyProc which runs queries against TestTable
我希望使用同义词,这样如果我在Database1的上下文中执行sp_MyProc,它将使用Database2.TestTable。如果我在Database2的上下文中执行sp_MyProc,它将违反Database2.TestTable。但是,当我通过任一同义词执行sp_MyProc时,它会忽略同义词的上下文并执行查找未找到的TestTable的本地副本。
有没有办法通过同义词或其他机制实现针对不同数据库中不同表的副本执行的共享存储过程?
修改
我应该提一下,在我的情况下,我希望用大量现有的表和过程来做这个,所以任何需要修改过程或表本身的解决方案都不理想。
答案 0 :(得分:3)
这样的东西可以用于程序的定义。请务必防止SQL注入,因为它是动态构建的。
CREATE PROCEDURE [dbo].dosomething
@databaseName sysname,
@schema sysname,
@tableName sysname
as
declare @cmd as nvarchar(max)
set @cmd = N'select * from ' + quotename(@schema) + N'.' + quotename(@tableName)
exec sp_executesql @cmd
然后像这样使用它:
dosomething 'SampleDb', 'dbo', 'sampleTable'
答案 1 :(得分:1)
如果存储过程在SharedDatabase中,那么它将始终在SharedDatabase的上下文中运行。为了完成你要集中代码的工作,我可能会传入一个参数来指定它来自哪个服务器,这样你就可以针对特定的TestTable执行查询。基本上,您需要使用其完全限定名称来引用每个表 - 即Database1.dbo.TestTable
USE SharedDatabase
CREATE PROCEDURE [dbo].sp_MyProc
@dbsource varchar(50)
as
if(@dbsource == 'DB1')
begin
select * from Database1.dbo.TestTable
end
else
begin
select * from Database2.dbo.TestTable
end
GO
另一种方法是在SharedDatabase中创建一个名为TestTableComposite的视图,其中有一个额外的列来标识源数据的位置。然后将其作为参数传递,并且SharedDatabase上的SP将始终位于该DB的上下文中。