2011-08-23 53 views
0

我有一个动态查询,我需要从不同的数据库发送给数据库的名称作为逗号分隔值和retreive数据选择数据ü可以帮助我out..i有以下查询从多个数据库

Decalre @DBname nvarchar(max); 
Declare @Selectstring nvarchar(max); 

set @Selectstring=' 

    select  

     Userid, 
     UserName, 
     CreatedOn, 
     IsActive as Status, 
     LastLoggedin 

    from 
     '[email protected]+'.dbo.UserDetails' 

    execute sp_executesql @[email protected] 

我正在执行此使用动态query..i要发送的

set @dbname='dbname1,dbname2,dbname3' 

每个数据库都有此表@DbName价值,我想从不同databases..Please所有这些表中获取数据帮助我如何做到这一点

+1

试着让它只与一个数据库一起工作,然后你可以扩展该解决方案来使用分割字符串函数或类似方法在逗号分隔的字符串中循环数据库名称。 –

+0

当像这样使用动态SQL时,您应该始终注意不要将自己暴露给SQL注入,就像执行此类方法时常见的那样。网上有几个关于如何保护自己的例子,这超出了这个问题的范围,但我觉得应该指出。一个简单的例子是假设:'SET @ DBname ='dbname1; UPDATE dbname1.dbo.UserDetails SET IsActive = 1; SELECT * FROM dbname1''这仍然适用于您的示例,但会导致更改基础数据 – Seph

回答

2

以下是一种假定在同一台服务器上有三个数据库(db1,db2,db3)的方法,它们具有一个名为table_1的公用表。它使用sys.databases(如果是sql2005或更新版本)来循环访问数据库,但在构建@dbname字符串时需要用单引号将每个数据库名称包围起来,以便将其正确用作IN子句的一部分

注意:如果需要,您可以将光标更改一段时间。

DECLARE @dbname NVARCHAR(MAX) 
SET @dbname='''db1'',''db2'',''db3''' 

EXEC (
'DECLARE @db NVARCHAR(255) 
DECLARE DB_CURSOR CURSOR FOR 
    SELECT tbl.name FROM 
     (SELECT db.name from sys.databases db WHERE db.name IN (' + @DBname + ')) as tbl 
    OPEN DB_CURSOR 
    FETCH NEXT FROM DB_CURSOR 
    INTO @db 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     EXEC(''SELECT * FROM '' + @db + ''.dbo.table_1'') 
     FETCH NEXT FROM DB_CURSOR INTO @db 
    END 
CLOSE DB_CURSOR 
DEALLOCATE DB_CURSOR' 
) 
0
declare @dbname varchar(max) 
select @dbname = 'master, model, msdb' 
declare @sql varchar(max) 
select @sql = isnull(@sql,'') 
    + case when @sql is null then '' else ' union all ' end 
    + 'select ''' + db.name + ''' dbname, *from ' + db.name + '.dbo.sysfiles' 
from sys.databases db 
where @dbname like '%' + db.name + '%' 

execute (@sql) 

这假定所有数据库的排序规则是相同的,并且将在一个单个结果与源数据库的名称作为列设置返回所有结果。但是,如果具有名称相似的数据库(如Database1和Database10),那么如果您将Database10作为参数传递,则这将返回Database1和Database10的结果,因为Database1是Database10的子字符串。

使用表变量作为输入或以其他方式将csv字符串转换为具有拆分函数的表,然后连接到新表而不是使用“where @dbname like ...”语法,会更好。