Val*_*Val 13 t-sql conditional dynamic where-clause
没错,第十个条件列问题:
我正在编写一个存储过程,它接受一个映射到几个标志列之一的输入参数.筛选请求列的最佳方法是什么?我目前正在使用SQL2000,但即将转向SQL2008,所以如果可以的话,我会采用现代解决方案.
在sproc中查询的表格看起来像
ID ... fooFlag barFlag bazFlag quuxFlag
-- ------- ------- ------- --------
01 1 0 0 1
02 0 1 0 0
03 0 0 1 1
04 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
我想做点什么
select ID, name, description, ...
from myTable
where (colname like @flag + 'Flag') = 1
Run Code Online (Sandbox Code Playgroud)
所以,如果我打电话给exec uspMyProc @flag = 'foo'我,我会回到第1和第4行.
我知道我不能直接在SQL中用parens做这个部分.为了做动态SQL,我必须将整个查询填充到一个字符串中,在WHERE子句中连接@flag param,然后执行字符串.除了在进行动态SQL时我得到的肮脏感觉,我的查询相当大(我选择了几十个字段,加入了5个表,调用了几个函数),所以它是一个巨大的字符串,因为一行在3行WHERE过滤器中.
或者,我可以有4个查询副本,并在CASE语句中选择它们.这使得SQL代码可以直接执行(并且受语法高亮等影响)但是以重复大块代码为代价,因为我不能仅在WHERE子句上使用CASE.
还有其他选择吗?可以应用任何棘手的连接或逻辑操作?或者我应该克服它并执行动态SQL?
Gab*_*ams 20
有几种方法可以做到这一点:
您可以使用case语句执行此操作.
select ID, name, description, ...
from myTable
where CASE
WHEN @flag = 'foo' then fooFlag
WHEN @flag = 'bar' then barFlag
END = 1
Run Code Online (Sandbox Code Playgroud)
你可以使用IF.
IF (@flag = 'foo') BEGIN
select ID, name, description, ...
from myTable
where fooFlag = 1
END ELSE IF (@flag = 'bar') BEGIN
select ID, name, description, ...
from myTable
where barFlag = 1
END
....
Run Code Online (Sandbox Code Playgroud)
您可以使用带有大量括号的复杂where子句.
select ID, name, description, ...
from myTable
where (@flag = 'foo' and fooFlag = 1)
OR (@flag = 'bar' and barFlag = 1) OR ...
Run Code Online (Sandbox Code Playgroud)
你可以用动态sql做到这一点:
DECLARE @SQL nvarchar(4000)
SELECT @SQL = N'select ID, name, description, ...
from myTable
where (colname like ''' + @flag + 'Flag'') = 1'
EXECUTE sp_ExecuteSQL @SQL, N''
Run Code Online (Sandbox Code Playgroud)
还有更多,但我认为其中一个会让你前进.
| 归档时间: |
|
| 查看次数: |
18327 次 |
| 最近记录: |