can i write a loop inside a function that has if then else if conditions?

前端 未结 2 358
被撕碎了的回忆
被撕碎了的回忆 2021-01-28 01:56

content : i am writing a function to return a value based on 3 conditions, but i need to write a loop inside it so it can check the conditions for each id passed. can i write t

相关标签:
2条回答
  • 2021-01-28 02:19

    It is hard for us to reverse engineer business logic from broken code. It is easier to understand clearly stated rules. So this is my interpretation of what you want:

    For a given id:

    1. return level 1 if it has distinct codes matching only ('TF','TB','TY','TL','TS')
    2. return level 2 if it has other codes not matching ('TF','TB','TY','TL','TS')
    3. return level 3 if it has null codes
    4. else return level 4 (e.g. when NO_DATA_FOUND)
    create or replace FUNCTION          fwt_get_holds(
        i_id  id.table_im%TYPE
    ) RETURN VARCHAR2 IS
        l_level1 number := 0;
        l_level2 number := 0;
        l_level3 number := 0;
        l_level4 number := 0;
    BEGIN 
      begin
        SELECT count(case when sprhold_hldd_code in ('TF','TB','TY','TL','TS') then 1 end ) as lvl_1
               , count(case when sprhold_hldd_code LIKE 'T%' and sprhold_hldd_code not in ('TF','TB','TY','TL','TS') then 1 end ) as lvl_2
               , count(case when sprhold_hldd_code is null then 1 end ) as lvl_3
        into l_level1
             , l_level2
             , l_level3
          FROM sprhold,
               stvhldd
          WHERE stvhldd_code = sprhold_hldd_code
          AND sprhold_to_date >= trunc(sysdate)
          AND sprhold_pidm = i_id;
        exception
          when others then 
            l_level4 := 1;
       end;
       if l_level4 != 0 then 
          return 'level 4';  -- no data found ?
       elsif l_level3 != 0 then 
          return 'level 3';  -- found some nulls
       elsif l_level2 != 0 then 
          return 'level 2';  -- found some non-matching codes
       else
         return 'level 1';   -- found only matching codes
      end if; 
    END fwt_get_holds;
    

    Quite possibly this is not what you want. If so, I suggest you edit your question to explain your business rules, as I did at the top of this answer.

    0 讨论(0)
  • 2021-01-28 02:29

    The way I see it, nothing of what you want will happen. Bad news, eh?

    Code you wrote is wrong - not because of obvious mistakes, but - cursor's SELECT statement contains 3 columns which you're fetching into a 1 varchar2 variable. 3 can't fit into 1; not that way, that is.


    Moreover, what would you do with a loop within the function? It can be done, of course, for example (switching to cursor FOR loop for simplicity), but - depending on where you put RETURN, you'll either return the first O_RESULT value or the last (see comments within the code):

    for cur_r in (select sprhold_hldd_code, ...
                  from sprhold ...
                  where --> ID condition missing here; ID you're passing, allegedly
                 )
    loop
      if cur_r.sprhold_hldd_code in ('TL', 'TY', ...) then ...
         -- in a number of IFs, you find what O_RESULT variable is
      end if;
    
      -- if you put RETURN here, only one loop iteration will execute
    
    end loop;
    
    -- if you put RETURN here, only the last O_RESULT value will be returned
    

    It means that you'd actually want to put a loop OUTSIDE of the function, i.e. call the function in a loop for all those IDs you're about to pass to the function. Something like this:

    function f_result (par_id in number) return varchar2 is
      o_result varchar2(20);
    begin
      select sprhold_hldd_code
        into l_sprhold_hldd_code
        from sprhold ...
        where some_id = par_id;
    
      if l_sprhold_hldd_code in ...
         -- find O_RESULT in a number of IFs
      end if;
    
      return o_result;
    end;
    

    Now call it in a loop

    begin
      for cur_r in (select id from some_table where some_condition) loop
        dbms_output.put_line('For ID = ' || cur_r.id || ', function returned ' || f_result(cur_r.id));
      end loop;
    end;
    

    If none of above helps, try to rephrase the question.

    0 讨论(0)
提交回复
热议问题