Как я могу иметь несколько CASE в операторах выбора в функции PL / SQL? - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь написать функцию, которая имеет 2 оператора case. Для фона у пользователя могут быть либо A, B, либо оба A и B (но в отдельных строках, поэтому я не могу использовать один оператор case, если я не использую LISTAGG, что мне сказали не делать для это.

Пример данных:

User State 
1       A 
1       B 
2       A 
3       B

SQL

CREATE OR REPLACE Function F_Calc_State(code Varchar2, id Number, time varchar2) Return Varchar2 AS

    Calc_State(10) := null;

    l_A varchar2(10) := null;
    l_B varchar2(10) := null;

BEGIN

    SELECT CASE WHEN state = 'A' THEN 'A'
                ELSE null 
           END into l_A,   
           CASE WHEN state = 'B' THEN 'B'
                ELSE null 
           END into l_B
      FROM TABLE1
     WHERE state in ('A', 'B')
       AND TABLE1_CODE = code
       AND TABLE1_ID   = id
       AND TABLE1_TIME = time;

    CASE WHEN l_A = 'A' and l_B = 'B' then 'AB'
         WHEN l_A = 'A' THEN 'A'
         WHEN 1_B = 'B' THEN 'B'
         ELSE stafford_recip_ind :='NEITHER';
    END CASE;

    RETURN Calc_State;

EXCEPTION
    WHEN NO_DATA_FOUND THEN 
        RETURN 'NO DATA';
    WHEN OTHERS THEN 
        RETURN SQLERRM ;
END  F_Calc_State;`

Для получения желаемых результатов, когда я ввожу пользователя 1, я хочу, чтобы AB возвращался, для пользователя 2 = A и пользователя 3 = B. Я также пытался иметь два разных блока операторов выбора, но не мог заставить это работать , он просто поразит обработчик исключений по какой-то причине. Спасибо!

Ответы [ 3 ]

0 голосов
/ 04 мая 2018

Очень тривиальный подход может быть таким: Не ясно, хотите ли вы проверить наличие записей или нет, так как в вашем блоке исключений вы возвращаете «NO DATA», в то время как в вашем выражении case у вас есть значение «NEITHER» ... в любом случае, вы можете настроить это соответствующим образом:

CREATE OR REPLACE Function F_Calc_State( code varchar2
                                       , id number
                                       , time varchar2
                                       ) return varchar2 
as
  l_count_a number;
  l_count_b number;
  l_result varchar2(10);

begin

  select count(*)
    into l_count_a
    from table1
   where state = 'A'
     and table1_code = id
     and table1_time = time;

  select count(*)
    into l_count_b
    from table1
   where state = 'B'
     and table1_code = id
     and table1_time = time;

  if    l_count_a = 0 and l_count_b = 0 then l_result := 'NEITHER'; 
  elsif l_count_a > 0 and l_count_b = 0 then l_result := 'A';
  elsif l_count_a = 0 and l_count_b > 0 then l_result := 'B';
  elsif l_count_a > 0 and l_count_b > 0 then l_result := 'AB';
  else  l_result := '';
  end if;

  return l_result;
end F_Calc_State;
0 голосов
/ 04 мая 2018

Следующий код вернет NULL, если данные не найдены:

CREATE OR REPLACE Function F_Calc_State (
    in_code Varchar2,
    in_id Number,
    in_time varchar2  -- "time" as a string is highly suspicious
) Return Varchar2 
AS
    v_ab varchar2(10) := null;
BEGIN

    SELECT MAX(CASE WHEN t1.state = 'A' THEN 'A' END) ||
           MAX(CASE WHEN t1.state = 'B' THEN 'B' END)
    INTO v_AB
    FROM  TABLE1 t1
    WHERE t1.state in ('A', 'B') AND
          t1.TABLE1_CODE = in_code AND
          t1.TABLE1_ID = in_id AND
          t1.TABLE1_TIME = in_time;    
    RETURN(v_ab);
END;  -- F_Calc_State

Однако, это не возвращает, возвращает ошибку, если данные не найдены.

CREATE OR REPLACE Function F_Calc_State (
    in_code Varchar2,
    in_id Number,
    in_time varchar2  -- "time" as a string is highly suspicious
) Return Varchar2 
AS
    v_ab varchar2(10) := null;
BEGIN

    SELECT MAX(CASE WHEN t1.state = 'A' THEN 'A' END) ||
           MAX(CASE WHEN t1.state = 'B' THEN 'B' END)
    INTO v_AB
    FROM  TABLE1 t1
    WHERE t1.state in ('A', 'B') AND
          t1.TABLE1_CODE = in_code AND
          t1.TABLE1_ID = in_id AND
          t1.TABLE1_TIME = in_time;  
    GROUP BY t1.TABLE1_CODE;  -- this will return no rows if there are no matches

    RETURN(v_ab);

    EXCEPTION
        WHEN NO_DATA_FOUND THEN RETURN 'NO DATA';
        WHEN OTHERS THEN RETURN SQLERRM ;

END;  -- F_Calc_State
0 голосов
/ 04 мая 2018

Используйте код ниже, теперь вы получите только одну строку результата.

SELECT MAX(CASE WHEN state = 'A' THEN 'A'
                ELSE null END),    
       MAX(CASE WHEN state = 'B' THEN 'B'
                ELSE null END)
INTO l_A, l_B
FROM TABLE1
 WHERE state in ('A', 'B')
   AND TABLE1_CODE = code
   AND TABLE1_ID   = id
   AND TABLE1_TIME = time;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...