我必须创建一个pl / sql函数,它接受七个输入参数。
问题是用户可以以任何组合传递任何这些参数,使得剩余参数为空。因此,许多组合是可能的。我必须在删除空参数后使用这些参数查询表。
有没有办法在不使用嵌套ifs数来检查空值的情况下执行此操作?
答案 0 :(得分:3)
在WHERE子句
中,检查输入参数是否为null例如,假设输入参数是parameter1,parameter2,parameter3
select * from tableA
where (col1 = parameter1 or parameter1 is null)
and (col2 = parameter2 or parameter2 is null)
and (col3 = parameter3 or parameter3 is null)
如果parameter1为null,则对于此参数的条件,它将始终返回true。
答案 1 :(得分:2)
1解决方案是在where子句中使用逻辑来短路条件
e.g:
SELECT blah WHERE (param1 IS NOT NULL AND col1=param1)
OR (param2 IS NOT NULL AND col2=param2) ….etc
注意:没有参数=没有结果
或
SELECT blah WHERE (param1 IS NULL OR col1=param1)
AND (param2 IS NULL OR col2=param2) ….etc
注意:没有参数=所有结果
答案 2 :(得分:2)
您可以使用
select * from table t where
(param1 is null or t.column1 = param1) and
(param2 ....)
但这会 NOT 使用表格中的任何索引,或者在最坏的情况下,使用不合适的索引(由于光标共享,在11G之前无法避免。在11G中它有时可能有效但这不是你应该依赖的东西。)
要获得更好的解决方案,您必须使用动态查询。在PLSQL中,这是在大多数情况下使用execute immediate l_query; (or open cursor for l_query;)
完成的,或者通过更强大的(但使用起来要复杂得多)DBMS_SQL
(在非常有限的出现次数中需要)来完成。
更简单(但使用文字因此几乎在运行时需要进行硬解析)解决方案
procedure dynamic_query_literals (param1 ... param7)
is
l_query varchar2(1000);
l_cursor sys_refcursor;
begin
l_query := 'select * from table t where 1=1';
if (param1 is not null) then
l_query := l_query || ' and t.column1 = param1';
end if;
if (param2 ...)
open l_cursor for l_query;
-- do whatever needed with the result set in the cursor.
--The procedure can even return this cursor...
end;
更复杂但性能更高(特别是如果这个过程被多次调用)解决方案需要绑定参数(当你在plsql中使用静态sql时,它会自动透明地完成)
procedure dynamic_query_binding (param1 ... param7)
is
l_query varchar2(1000);
l_cursor sys_refcursor;
begin
l_query := 'select * from table t where 1=1';
if (param1 is null) then
--this will get optimised away in the process but is required
--syntactically for use of "using" later
l_query := l_query || ' and 1=1 or :param1 is null';
else
l_query := l_query || ' and t.column1 = :param1';
end if;
if (param2 ...)
open l_cursor for l_query
using param1, param2, ... param7;
-- do whatever needed with the result set in the cursor.
-- The procedure can even return this cursor...
end;
此版本将根据需要使用表格中的索引,并且每个参数的“无效”组合仍然只能获得一次硬分析。
这两个动态版本的缺点是你没有得到编译时语法检查。
答案 3 :(得分:0)
您可以使用以下内容:
select * from tableA
where col1 = nvl(parameter1, col1)
and ....