从不同的数据库运行存储过程

时间:2011-06-27 18:39:37

标签: sql sql-server tsql sql-server-2008

所以我在db中有一个sproc ..让我们调用这个db A。此数据库在另一个数据库中使用表(t1, t2)。让我们调用这个db B

好的,所以我现在称之为的方式是:A.dbo.My_Proc但是我得到了另一个错误:

  

无效的对象名称'dbo.t1'。

所以我如何尝试提供参数。在我的Sproc中,select * from @dbname.dbo.t1 但是这会导致错误。我不能把sproc放在db B中。

虽然硬编码就足够了(如果有办法),db B每年都会发生变化,所以“提供”数据库会很好。

我尝试使用use B; go,但它给了我一个错误,说不能在sproc中有这个。

2 个答案:

答案 0 :(得分:1)

您可以创建同义词:

编辑:我现在看到表格需要同义词,而不是proc。让他们切换。因此,您可以在数据库A中为数据库B中的表创建同义词:

USE A;
CREATE SYNONYM dbo.t1 FOR B.dbo.t1;

然后你在A的程序可以简单地说:

SELECT * FROM dbo.t1;

根本不需要手动提供数据库名称,查询知道(基于同义词)从数据库B中的表中获取数据。当数据库B更改为C时,您可以简单地:

DROP SYNONYM dbo.t1;
CREATE SYNONYM dbo.t1 FOR C.dbo.t1;

如果您在叙述中使用“真实”数据库名称而不是任意A / B名称,则可能会更容易理解。只是一个建议。 : - )

<强> /修改

另一种选择是传入数据库名称并通过动态SQL构造。例如。而不是select * from @ dbname.dbo.t1(这将永远不会起作用),你可以这样做:

DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM ' + QUOTENAME(@dbname) + '.dbo.t1;';
EXEC sp_executesql @sql;

但如果这个其他数据库名称实际上每年只更改一次,我建议同义词路由整体更好。

答案 1 :(得分:1)

执行exec someDB.dbo.SomeProc时,执行上下文切换到someDB。因此,如果该过程发出SELECT FROM dbo.t1,那么dbo.t1必须位于someDB。如果您希望该过程从“提供的”数据库中进行选择,则该过程必须使用dynamic-SQL

create procedure someProc
   @dbname sysname
as
begin
...
set @sql = N'SELECT ... FROM ' + quotename(@dbname) +N'.dbo.t1';
exec sp_executesql @sql;
...
end