我有这段代码:
SELECT idcallhistory3, callid, starttime, answertime, endtime, duration,
is_answ, is_fail, is_compl, is_fromoutside, mediatype, from_no,
to_no, callerid, dialednumber, lastcallerid, lastdialednumber,
group_no, line_no
FROM "public".callhistory3
WHERE (starttime >= ?) AND (endtime <= ?) AND (is_fromoutside = ?)
AND (from_no = ?) AND (to_no = ?)
问题是我需要传递一个值吗?并获得没有过滤器的所有结果,有些像*
任何帮助?
答案 0 :(得分:7)
WHERE
(@start is null OR starttime >= @start) AND
(@end is null OR endtime <= @end) AND
(@fromOutside is null OR is_fromoutside = @fromOutside) AND
(@fromNo is null OR from_no = @fromNo) AND
(@toNo is null OR to_no = @toNo)
为所有参数传递空值(dang sql nulls;感谢GC)。
答案 1 :(得分:3)
我喜欢COALESCE。
你只需要小心左侧的空值,如果左侧可以有空值,你可以做类似于最后一行的操作,以便空值匹配。通常情况下,你会想确保你的查询仍能正常运行。
SELECT idcallhistory3, callid, starttime, answertime, endtime, duration,
is_answ, is_fail, is_compl, is_fromoutside, mediatype, from_no,
to_no, callerid, dialednumber, lastcallerid, lastdialednumber,
group_no, line_no
FROM "public".callhistory3
WHERE (starttime >= COALESCE(@starttime, starttime ))
AND (endtime <= COALESCE(@endtime, endtime))
AND (is_fromoutside = COALESCE(@is_fromoutside, is_fromoutside))
AND (from_no = COALESCE(@from_no, from_no))
AND (COALESCE(to_no, -1) = COALESCE(@to_no, to_no, -1)) -- make nulls match
答案 2 :(得分:2)
对于具有多个可选节的复杂查询,您可能会发现最好创建适合的SQL。您可以在调用者(例如,在C#中)或在数据库中(至少在SQL Server中)执行此操作 - 但无论如何,必须确保它仍然参数化。在调用者完成工作的情况下,只需在命令中添加合适的参数即可。如果db正在生成TSQL,那么该方法取决于RDBMS。使用SQL-Server,sp_ExecuteSql
是您的朋友 - 即您可以根据查询构建@cmd
变量,然后:
EXEC sp_ExecuteSQL @cmd, N'@someArg int', @actualArg
@someArg
是@cmd
内的声明,@actualArg
是执行时传入的值。
答案 3 :(得分:1)
这样做的典型方法如下:
WHERE (? IS NULL OR starttime >= ?)
然后传入DBNull.Value。显然,您需要为每个参数执行此操作,以便能够像这样“通配”。
答案 4 :(得分:1)
有条件地添加“Where”语句 - 仅当您需要过滤结果时
答案 5 :(得分:0)
我同意贾马尔·汉森的观点。到目前为止,COALESCE是最佳表现方式,至少在SQL Server上是