2012-03-15 89 views
0

我試圖使動態SQL它可以獲取所有任務對一些用戶 我寫這些CURENT用戶的所有subalterns的SQL Server不允許執行子查詢的動態SQL

的程序[GetAllSubExecutorsByUserId]返回標識ID添加到一個臨時表,之後,我想使動態SQL擺脫[任務]表中的所有任務,其中「執行人」列在這個臨時表中的值

我寫的查詢如下:

DECLARE @UserId VARCHAR(10) = 72; 

DECLARE @tmp TABLE (Id VARCHAR(10)); 
INSERT @tmp exec [dbo].[GetAllSubExecutorsByUserId] @Source = @UserId; 

DECLARE @SQL VARCHAR(max); 

SELECT @SQL = 'SELECT * FROM tasks '; 
SELECT @SQL = @SQL + 'WHERE Executor IN (' + (select Id from @tmp) + ')'; 

EXEC(@SQL); 

卜t當我運行它,它給出了一個錯誤:

子查詢返回多個值。當子查詢遵循=,!=,<,< =,>,> =或當子查詢用作表達式時,這是不允許的。

,我可以不知道如何解決它,因爲如果我運行相同的查詢(這不是它的工作原理完全動態SQL)

其運作的查詢是靜態的:

DECLARE @UserId VARCHAR(10) = 72; 

DECLARE @tmp TABLE (Id VARCHAR(10)); 
INSERT @tmp exec [dbo].[GetAllSubExecutorsByUserId] @Source = @UserId; 

SELECT * FROM tasks WHERE Executor IN (select Id from @tmp) 

但我需要一個動態SQL ... 請幫我解決這個問題。

謝謝。

回答

2

這是因爲您試圖從select返回多個值來設置字符串值。 SQL不知道如何將這個列表轉換成逗號分隔的列表。在準備好的語句中,它針對返回的「表」運行爲真IN,因此它可以針對該子查詢表運行SET運算符。在動態查詢,你基本上是試圖建立這樣的事情,雖然:

...IN (1,2,3) 

您必須重寫像下面的動態查詢得到它就像準備好的語句運行:

'WHERE Executor IN (select Id from @tmp)' 

如果你這樣做,那麼你將不得不將表變量傳遞給exec,但是你必須使用sp_executesql。所以,你的代碼就變成了:

DECLARE @UserId VARCHAR(10) = 72; 

DECLARE @tmp TABLE (Id VARCHAR(10)); 
INSERT @tmp exec [dbo].[GetAllSubExecutorsByUserId] @Source = @UserId; 

DECLARE @SQL VARCHAR(max); 

SELECT @SQL = 'SELECT * FROM tasks '; 
SELECT @SQL = @SQL + 'WHERE Executor IN (select Id from @tmp)'; 

DECLARE @SQLParamSetup VARCHAR(150); 
SET @SQLParamSetup = '@tmp TABLE (Id VARCHAR(10))' 


EXEC sp_executesql @SQL, @SQLParamSetup, @tmp ; 

然而,另一種更簡便的是使用臨時表(不變量),因爲它會在你的連接(即使是在孩子的查詢)

活路
DECLARE @UserId VARCHAR(10) = 72; 

CREATE TABLE #tmp (Id VARCHAR(10)); 
INSERT INTO #tmp exec [dbo].[GetAllSubExecutorsByUserId] @Source = @UserId; 

DECLARE @SQL VARCHAR(max); 

SELECT @SQL = 'SELECT * FROM tasks '; 
SELECT @SQL = @SQL + 'WHERE Executor IN (select Id from #tmp)'; 

EXEC @SQL ; 
+0

據我所知,我應該得到「從@tmp選擇ID」子查詢作爲CSV字符串的結果......但sp_executesql怎麼辦?> – meorfi 2012-03-15 14:12:03

+1

我不知道你在哪裏得到了理解,但那不是真的子查詢將轉換爲CSV。我將更新我的答案,以顯示如何使用sp_executesql如描述 – 2012-03-15 14:19:15

+0

謝謝Justin! – meorfi 2012-03-15 14:34:03

0

使用sp_executesql,您可以傳入參數。

+0

謝謝,但我不明白什麼通過作爲參數... – meorfi 2012-03-15 14:04:43

+1

那麼你有什麼是真的很簡單,不需要動態SQL所以我猜你有一個更復雜的查詢,但你可以傳遞你的表變量作爲參數供動態SQL使用 – 2012-03-15 14:22:39