动态查询与动态子查询

时间:2017-01-09 21:35:51

标签: sql-server tsql

我正在尝试(并且失败)使用子查询创建动态查询。 我有一个问题表,其中每个问题的可能答案需要从一个或多个其他表动态创建。我在问题表中有一个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);

抱歉格式不佳!

我正在尝试做什么?

4 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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注入 - 这么好。

答案 2 :(得分: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);

答案 3 :(得分: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字符串。