2010-06-05 96 views
3

我們已經有了一個系統(基於MS SQL 2008 R2),它有一些「輸入」數據庫和一個「輸出」數據庫。我想編寫一個查詢,它將從輸出數據庫中讀取數據,並將其寫入源數據庫之一中的數據。但是,源表可能是一個或多個單獨的表:(源DB的名稱包含在輸出DB中;理想情況下,我想要執行類似下面的操作(僞SQL SQL語句)來自多個表的SQL連接

select o.[UID] 
     ,o.[description] 
     ,i.[data] 
from [output].dbo.[description] as o 
    left join (select [UID] 
        ,[data] 
       from 
        [output.sourcedb].dbo.datatable 
       ) as i 
     on i.[UID] = o.[UID]; 

有沒有什麼辦法可以做到上面的事情 - 「動態」指定查詢中每一行要加入的數據庫和表?

回答

1

不,該表必須在準備查詢時知道。否則,查詢優化器如何知道它可能能夠使用的索引?或者如果你引用的表甚至有一個UID列?

你必須做到這一點的階段:

  1. 取在一個查詢從輸出數據庫sourcedb值。

  2. 構建一個SQL查詢字符串,將您在第一個查詢中獲取的值插入到第二個查詢的FROM子句中。

    請小心檢查此值是否包含合法的數據庫名稱。例如,過濾非字母字符或應用正則表達式或在白名單中查找它。否則,你將面臨着一個SQL Injection的風險。

  3. 如@ user353852所示,執行您使用exec()構建的新SQL字符串。

2

嘗試使用exec函數,然後指定select作爲字符串,在適當的地方添加數據庫名稱和表格的變量。簡單示例:

DECLARE @dbName VARCHAR(255), @tableName VARCHAR(255), @colName VARCHAR(255) 
... 
EXEC('SELECT * FROM ' + @dbName + '.dbo.' + @tableName + ' WHERE ' + @colName + ' = 1') 
+0

我以前從來沒有見過exec函數,但是沒有辦法像這樣。我知道在SQL附近的字符串連接是一個壞主意。 – colinmarc 2010-06-05 14:43:14

+1

如果你正在談論注入,那麼你是對的,你根本不會從用戶數據加載變量dbName等的值。這些變量不應該由用戶數據填充,而應該來自環境設置。例如在Freds環境中,他的數據庫是'fred',而在Barneys環境中,他的數據庫是'barney',所以應該根據這個變量設置變量。 – krock 2010-06-05 15:06:06