2011-08-23 28 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 ...」語法,會更好。