SQL Server - 执行动态布尔字符串作为WHERE条件

时间:2013-07-28 20:54:55

标签: sql sql-server boolean dynamic-sql

我有一个布尔表达式存储为我的一个表中的字符串,并希望使该记录显示的条件。

表: Answer_CFG = [answer_Id],[Quest_ID],[条件]

例如:

'(SELECT findAns(1,1)as AnsID)<> 4'存储在'条件'列

(findAns(a,b)是我制作的udf返回一个int)

DECLARE @sqlCommand nvarchar(MAX)
DECLARE @cond nvarchar(MAX)


SELECT @sqlCommand= 'SELECT Answer_ID FROM Answer_CFG as ans1 WHERE ans1.Quest_ID=@QuestionID AND (SELECT Condition from Answer_CFG as ans2 WHERE ans2.answer_ID=ans1=Answer_ID)' 

SET @sqlCommand = REPLACE(@sqlCommand, '@QuestionID', @QuestionID)


EXEC (@sqlCommand)

现在它甚至不会执行我存储在那里的udf但是即便如此,我尝试自己执行该语句并且它会执行udf但是在尝试比较时会抛出错误('<>' ,'< ='etc ....)

如果有可能,请告诉我。我想尝试一些聪明的东西,但在这一点上可能只是一种愚蠢的努力。

出于条件下拉菜单的目的,这与asp.net/C#相关联。我宁愿不必硬编码一堆if语句。

由于

2 个答案:

答案 0 :(得分:1)

您必须将[condition]值提取到某个@variable,然后通过添加它来构建您的@sqlCommand,例如

select @sqlCommand='select ...whatever you want... where '+@variable

你必须知道100%,没有人会添加像1=1 drop table students;)

这样的条件

*你也不需要使用REPLACE,最好使用sp_executesql,它可以将参数传递给查询:

exec sp_executesql @sqlCommand,'@QuestionID int', @QuestionID

答案 1 :(得分:0)

您需要使用存储在表中的条件构建组成固定部分的最终查询。你的代码中的问题是它只是从表中选择SELECT,而不是组成任何语句。完全有可能做你想做的事(即使它被广泛认为是糟糕的做法)。您需要分两步完成,首先检索条件,然后在最终查询中合并它:

DECLARE @sqlCommand NVARCHAR(MAX) ;
DECLARE @cond NVARCHAR(MAX) ;
DECLARE @Id INT = 1 ;   --Replace with the actual ID you want

--Get the condition string from table
SELECT @cond = Condition FROM Answer_CFG WHERE answer_ID=@Id ;

--Build the final query by concatenating the initial, fixed part with the condition extracted
SET @SqlCommand = 'SELECT Answer_ID FROM Answer_CFG as ans1 WHERE ans1.Quest_ID=@QuestionID AND ' + @cond ;

EXEC sp_executesql @sqlCommand,'@QuestionID INT', @QuestionID ;

修改

似乎还有一个问题,即每行要求获得不同的条件,所以我写的方法并不那么容易。问题是我们不能使用相同的查询,但每行需要不同的查询。这是最终应该执行的代码:

SELECT Answer_ID FROM Answer_CFG as ans1 WHERE ans1.Quest_ID=@QuestionID AND 1=1;
SELECT Answer_ID FROM Answer_CFG as ans1 WHERE ans1.Quest_ID=@QuestionID AND answ_id=38;
SELECT Answer_ID FROM Answer_CFG as ans1 WHERE ans1.Quest_ID=@QuestionID AND something>otherthing;

最终条件总是不同的。假设这没关系,我已经有了问题,试试这个:

DECLARE @SqlCommand NVARCHAR(MAX) = '' ;

--Compose a SQL query for each row
SELECT @SqlCommand = @SqlCommand + 'SELECT Answer_ID FROM Answer_CFG as ans1 WHERE ans1.Quest_ID=@QuestionID AND ' + Condition + ';' + CHAR(13) + CHAR(10)FROM Answer_CFG ;

--See what actually gets executed
PRINT @sqlcommand ;

--Execute the multitude of SELECTs all at once
EXEC sp_executesql @sqlCommand,N'@QuestionID INT', @QuestionID ;

问题在于它为表中的每一行发出一个查询,导致每行查询一个结果集。通过在它生成的查询字符串中添加UNION ALL,可以很容易地修复,具体取决于您的需求。