所以我在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中有这个。
答案 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