1

say i have the following function:

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;

Now, in the current PL/SQL code, we have this:

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;

I wanted to code it like this to make it shorter:

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;    

The code above tells me If l_optin is 'N' then evaluate xx1.t_col3 = xx2.t_col3. if l_optin = 'Y', then don't evaluate xx1.t_col3 = xx2.t_col3. I tried testing it locally and it works but my co-worker says it won't work on all scenarios. The columns are not nullable.

Are there any possible scenarios that this wouldn't handle?

Note:

  • We cannot use Dynamic SQL
  • this sample code occurs multiple times in the package of over 14000 lines, hence, it's quite hard to read at that point.
6
  • 3
    From my point of view, as you aren't charged by number of characters you type, use option which is easier to follow and maintain. First code you posted is simple - if function returns Y, do this; otherwise, do that. Your second code looks smarter, but - is it more efficient? Imagine someone who inherits your code. Imagine yourself inheriting a) simple code, b) complex code. Which one would you prefer? I'm not saying that this example is that complex; it's just that I prefer having it simple. Commented Oct 25, 2021 at 18:28
  • 4
    Ask your co-worker for scenarios where it wouldn't work, because there aren't any as far as I am concerned (none that also wouldn't work for the original query at least. If you want to make the code shorter, I question the use of 1=1 as part of the WHERE clause, AFAIK that's only useful if you are already using dynamic SQL and need to ensure a valid where clause to append to. Commented Oct 25, 2021 at 18:31
  • Also if we are talking about style and readability, the OR in the second version is misleadingly placed and inconsistently capitalised. Commented Oct 25, 2021 at 20:44
  • @Littlefoot When someone has to come along and clean up that comma join, would they prefer to edit one query or two? :) Commented Oct 25, 2021 at 23:35
  • I agree with Connor. I have started writing answer recommending usage of ANSI joins and breaking up logic of xx_func function into single SQL (i.e. ... from xx_table_1 xx1 join xx_table_2 xx2 on xx1.t_col2 = xx2.t_col2 left join func_table ft on ft.lookup = 'hello' where (ft.lookup is not null or xx1.t_col3 = xx2.t_col3)). Anyway I finally consider its readability disputable - the ANSI syntax is suitable for join chains of two tables at a time, here we actually have three tables, all involved in join condition in one go - and from performance point of view it is not clear winner too. Commented Oct 26, 2021 at 7:22

1 Answer 1

2

For every person that argues for a SQL statement per requirement (ie, 2 statements above) there will be a person that argues for getting as much "bang for your buck" out of a single SQL (1 statement above), so I'm not going to try tell you which is right or wrong.

My preference is generally multiple statements because I'm giving the optimizer the best chance at a good plan, but there is no rule, because 2 statements might be fine, but 200 sounds like I've taken things too far etc.

Similarly, the two are not mutually exclusive - I've seen code where there are multiple permutations possible and thus the most common usages are coded in static SQL with a "fallthrough" option being dynamically built SQL for the rare permutations.

You pick what you are comfortable with, whilst meeting the goals of maintainability and keeping things simple for the optimizer.

Whilst I assume your examples are pseudo-code, just in case they are indeed representative of your real code

  • you don't need "where 1=1"
  • if the "col2" join yields a single row, how can "col2/col3" pairing yield anything different?
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.