我正在创建一个报告工具,用户可以在其中选择一个运算符和2个值进行过滤.
我的基本表:
UserID UserName
-------------------------------
1 User1
2 User2
3 User3
4 User4
5 User5
Run Code Online (Sandbox Code Playgroud)
用户可以选择我想要翻译的运算符,如下所示:
Option SQL Operator
------------------------------
between column between x and y
like column '%' + x + '%'
greater than column > x
less than column < x
equal to column = x
not equal to column <> x
Run Code Online (Sandbox Code Playgroud)
我在想类似的东西:
... column = ISNULL(@parameter, column)
Run Code Online (Sandbox Code Playgroud)
从某种意义上说,如果你传递的东西或什么都没有,它仍然会正确查询.
这是我正在玩的TSQL(**不工作*):
declare @bwValue1 varchar(200) = '2', --between value 1
@bwValue2 varchar(200) = '4'; --between value 2
select * from users where
(UserID BETWEEN @bwValue1 AND @bwValue2
OR UserID != @bwValue1
OR UserID = @bwValue1
OR UserID < @bwValue1
OR UserID > @bwValue1
OR UserID LIKE '%' + @bwValue1 + '%');
Run Code Online (Sandbox Code Playgroud)
有没有办法编写一个TSQL,可以正确评估语句,无论选择哪个运算符?
*最终答案*
以下是我对任何好奇的人的最终结果:
declare @fn varchar(200) = 'carl',
@Op varchar(3) = 'bw',
@bwValue1 varchar(200) = '978',
@bwValue2 varchar(200) = '2000'
select * from users where userfirstname like '%' + @fn + '%'
AND ((@Op = 'eq' AND (userid = @bwValue1))
OR (@Op = 'neq' AND (userid <> @bwValue1))
OR (@Op = 'lt' AND (userid < @bwValue1))
OR (@Op = 'gt' AND (userid > @bwValue1))
OR (@Op = 'li' AND (userid like '%' + @bwValue1 + '%'))
OR (@Op = 'bw' AND (userid between @bwValue1 and @bwValue2)))
Run Code Online (Sandbox Code Playgroud)
动态SQL并不意味着您无法对其进行参数化并缓存计划.工作正常,因为SQL Server无法区分.如果你的应用程序连接几个SQL字符串(不包含动态文字!)SQL Server会像对待任何其他查询一样对待它们.它缓解了计划.当然,每个运营商都会产生不同的计划.如果查询可以通过这种方式寻找索引,那么这甚至可能是你想要的!
因此,我建议您将查询设置为静态,但运算符除外.
如果您不能这样做并愿意放弃SARGability,请执行以下操作:
WHERE 0=0
OR (Operator = '=' AND (A = B))
OR (Operator = '<' AND (A < B))
OR (Operator = '>' AND (A > B))
---...
Run Code Online (Sandbox Code Playgroud)
恰好其中一个OR子句将在运行时变为"活动".它看起来仍然可读和可维护.
| 归档时间: |
|
| 查看次数: |
3751 次 |
| 最近记录: |