来自函数的静态SQL条件WHERE子句



假设我有以下函数:

function xx_func 
return varchar2
is
l_value varchar2(1);
begin
select  'Y'
into    l_value
from    func_table
where   lookup = 'hello';

RETURN l_value;

EXCEPTION
WHEN NO_DATA_FOUND THEN
l_value := 'N';
RETURN l_value;
end xx_func;

现在,在当前的PL/SQL代码中,我们有这个:

DECLARE
l_optin varchar2(100);
t_col1  varchar2(100);
BEGIN
l_optin := xx_func;

if l_optin = 'Y' then

select  col1
into    t_col1
from    xx_table_1 xx1
,   xx_table_2 xx2
where   1=1
and     xx1.t_col2 = xx2.t_col2;

else
select  col1
into    t_col1
from    xx_table_1 xx1
,   xx_table_2 xx2
where   1=1
and     xx1.t_col2 = xx2.t_col2
and     xx1.t_col3 = xx2.t_col3;

end if;

END;

我想这样编码,使它更短:

DECLARE
l_optin varchar2(100);
t_col1  varchar2(100);
BEGIN
l_optin := xx_func;

select  col1
into    t_col1
from    xx_table_1 xx1
,   xx_table_2 xx2
where   1=1
and     xx1.t_col2 = xx2.t_col2 
and     ((xx1.t_col3 = xx2.t_col3 and l_optin = 'N')
OR       (l_optin = 'Y'));

END;    

上面的代码告诉我If l_optin is 'N'然后evaluate xx1.t_col3 = xx2.t_col3. if l_optin = 'Y',那么不计算xx1.t_col3 = xx2.t_col3.我试着在本地测试它,它可以工作,但我的同事说它不能在所有情况下工作。列不可为空。

有没有可能的情况,这将无法处理?

注意:

  • 我们不能使用动态SQL
  • 此示例代码在超过14000的包中出现多次

对于每一个要求一个SQL语句(即上面的2个语句)的人来说,将会有一个人认为得到尽可能多的"物有所值"。从一个SQL语句(上面的1条语句)中,所以我不会试图告诉你哪个是对的或错的。

我的偏好通常是多个语句,因为我给优化器一个好的计划最好的机会,但没有规则,因为2个语句可能是好的,但200听起来像是我做得太远了等等。

同样,这两者也不是互斥的——我曾见过可能有多种排列的代码,因此最常见的用法是在静态SQL中使用&;fallthrough&;选项为罕见的排列动态构建SQL。

你选择你满意的,同时满足可维护性的目标,并使优化器保持简单。

虽然我假设你的例子是伪代码,只是以防他们确实代表你的真实代码

  • 你不需要"where 1=1">
  • 如果"col2"Join生成单行,如何&;col2/col3&;配对有什么不同吗?

最新更新