2017-01-09 144 views
0

我想(和失敗)創建一個子查詢動態查詢。 我有一個問題表,其中每個問題的可能答案都需要從一個或多個其他表中動態創建。我在問題表中有一個varchar字段,我想動態地使用它來查詢可能的答案。例如:動態查詢動態子查詢

問題表:

----------------------------------------------------------------------------- 
id | question   | answer_query 
----------------------------------------------------------------------------- 
1 | Can this be done? | SELECT field1 + ' ' + field2 answers FROM table1 a JOIN table2 b ON b.field1 = a.field2 WHERE b.id = '@id' 

然後,我希望有一個存儲過程創建這樣一個動態查詢:

DECLARE @id int 
SET @id....... 
DECLARE @sql_query varchar(3000); 
SET @sql_query = 
    'SELECT q.id, q.question, (REPLACE(q.answer_query, ''@id'', @id)) 
    FROM Questions q 
    JOIN Other Table ON .... 
    WHERE .....'; 

EXECUTE(@sql_query); 

道歉窮人格式!

正在嘗試做什麼?


+0

我的第一反應是:不這樣做。如果你打算做這樣的事情,從這裏開始:[動態SQL的詛咒和祝福 - Erland Sommarskog](http://www.sommarskog.se/dynamic_sql.html) – SqlZim

+0

作爲一般原則,如果你需要使用動態SQL,不要這樣做,就像你在這裏做的那樣,或者像McNets在他的回答中所建議的那樣(使用'EXEC()',即使McNets爲其他原因建議了一個不正確的答案)。改爲使用'EXEC sp_executesql'。它允許正確地參數化您的查詢。這篇文章描述了爲什麼它是[壞習慣](http:// sqlblog。COM /博客/ aaron_bertrand /存檔/ 2011/09/17 /壞習慣,對開球使用-EXEC-INSTEAD-OF-SP-executesql.aspx)。 – ZLK

回答

0

試試這個:

DECLARE @id int 
SET @id....... 
DECLARE @sql_query varchar(3000); 
SET @sql_query = 
    'SELECT q.id, q.question, ' 
    + (REPLACE(q.answer_query, '@id', @id)) 
    + ' FROM Questions q 
    JOIN Other Table ON .... 
    WHERE .....'; 

EXECUTE(@sql_query); 
0

你想

SET @sql_query = (SELECT REPLACE(q.answer_query, '@id', @id) 
    FROM Questions q 
    JOIN Other Table ON .... 
    WHERE .....) 

SELECT @sql_query = REPLACE(q.answer_query, '@id', @id) 
FROM Questions q 
JOIN Other Table ON .... 
WHERE .....) 

然而,這似乎是有很多原因一個非常糟糕的主意。有沒有其他辦法可以解決這個問題。

例如 - 不要在表中使用select語句,而要尊重視圖名稱。這解決了很多問題,編譯器可以優化你不打開sql注入 - 非常好。

0

我無法正確理解查詢。假設您要將answer_query中的字符串'@id'替換爲變量@id中的值。

如果是這樣,請嘗試以下查詢:

DECLARE @id int 
SET @id=..... 
DECLARE @sql_query varchar(3000); 
SET @sql_query = 
    'SELECT q.id, q.question, (REPLACE(q.answer_query, ''@id'', '+CONVERT(VARCHAR(10),@id)+')) 
    FROM Questions q 
    JOIN Other Table ON .... 
    WHERE .....'; 
EXECUTE(@sql_query); 
0

感謝所有爲您的意見。我提出了下面的解決方案,但並不像我想的那樣通用。

Table structure

存儲過程:

CREATE PROCEDURE [dbo].[spQuestionsByTypeAndOther] 
    @type_id uniqueidentifier, 
    @other_param_id uniqueidentifier 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT q.id, q.question, q.required, dbo.fnGetAnswers(q.id, @other_param_id) 
    FROM Questions q 
    JOIN QuestionsToTypes t on t.question_id = q.id 
    WHERE t.type_id = @type_id 
END 

和一個函數(fnGetAnswers),它使用case語句返回基於問題ID和一個其他參數的答案。每種情況下都會針對數據庫中的其他表執行不同的查詢,並將結果展平/連接成csv字符串。