2012-09-22 23 views
3

有没有办法通过一个TSQL功能的数据库名称,以便它可以在数据库传递一个TSQL函数的数据库名称

ALTER function [dbo].[getemailjcp] 
(
@DB_Name varchar(100) 
) 
Returns varchar(4000) 
AS 
BEGIN 
DECLARE @out varchar (4000); 
DECLARE @in varchar (1000); 
Set @out = 
(select substring 
((select ';' + e.email from 
(SELECT DISTINCT ISNULL(U.nvarchar4, 'NA') as email 
FROM [@DB_Name].dbo.Lists ... 
+0

你能证明你的整体功能,而不是'...'? –

+0

请问您的最终目标是什么,换句话说,您正试图解决什么问题?我不禁想知道是否有更优雅的方法在等待。 –

+0

对于大约200个左右的数据库,我需要检索到不同的信息片段。我们的代码工作时间太长了。我试图用一个函数替换游标,但再次查看了需求,并意识到我可以在两个foreachdb的顶层过程中执行我想要的操作,然后完成所有操作。谢谢。 – o365spo

回答

1

执行选择为了创建动态SQL语句,你应该存储过程。例如:

DECLARE @DynamicSQLStatement NVARCHAR(MAX) 
DECLARE @ParmDefinition NVARCHAR(500) 
DECLARE @FirstID BIGINT 

SET @ParmDefinition = N'@FirstID BIGINT OUTPUT' 
SET @DynamicSQLStatement=N' SELECT @FirstID=MAX(ID) FROM ['[email protected]+'].[dbo].[SourceTable]' 


EXECUTE sp_executesql @DynamicSQLStatement,@ParmDefinition,@[email protected] OUTPUT 

SELECT @FirstID 

在这个例子中:

  1. @DatabaseName被传递作为参数传递给你的程序。

  2. @FirstID是输出参数 - 此值可能会从您的过程中返回。

在这里您可以找到 “sp_executesql的” 详细信息:

http://msdn.microsoft.com/en-us/library/ms188001.aspx

+0

但是你不能在一个函数*中做这个*。我会假设OP试图将它移动到一个函数,以便他们可以称它为查询的每一行... –

+0

@AaronBertrand你说得对,“sp_executesql”可以在函数中执行,用户存储过程是必需的。 – gotqn

0

一个更好的解决方案可能是更换 “@DatabaseName”(一个字符变量):

“ DB_NAME(< @DBId>)“。

然后,您可以继续传递数据库名称,但是首先将它们转换为fcn中的ID。如果使用“sp_executesql”来帮助防范SQL注入(“DB_NAME()”不是变量/不能被替换),还可以解决构建其中包含char变量的SQL语句的矛盾。

所以你有这样的:

DECLARE @DynamicSQLStatement NVARCHAR(MAX) 
DECLARE @ParmDefinition NVARCHAR(500) 
DECLARE @FirstID BIGINT 
DECLARE @DBId INT 

SET @DBId = DB_ID(@Db_Name) --raise the proper security/robustness** concern if this doesn't resolve. 

SET @ParmDefinition = N'@FirstID BIGINT OUTPUT' 
SET @DynamicSQLStatement=N' SELECT @FirstID=MAX(ID) FROM ['+DB_NAME(@DBId)+'].[dbo].[SourceTable]' 
相关问题