假设我有以下函数:
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&;配对有什么不同吗?