PLSQL: использование подзапроса в ошибке if-инструкции PLS-00405 - PullRequest
0 голосов
/ 15 сентября 2018

Я получаю сообщение об ошибке pls-00405 при попытке запустить этот код:

BEGIN
  IF :P10_KAART_CODE IN (SELECT KAART_CODE FROM CADEAUKAART) THEN
     RETURN TRUE;
  ELSE
    RETURN FALSE;
  END IF;
END;

Есть несколько похожих вопросов по этому поводу, но не удалось найти решение для этого простого кода. Есть ли другой способ написать это без ошибки?

Ответы [ 4 ]

0 голосов
/ 15 сентября 2018

Еще один способ:

CREATE OR REPLACE FUNCTION IS_KAART_CODE_VALID(pinKAART_CODE IN CADEAUKAART.KAART_CODE%TYPE)
   RETURN BOOLEAN
IS
  nCount  NUMBER;
BEGIN
  SELECT COUNT(*)
    INTO nCount
    FROM CADEAUKAART
    WHERE KAART_CODE = pinKAART_CODE ;

  RETURN CASE
           WHEN nCount > 0 THEN
             TRUE
           ELSE
             FALSE
         END;
END IS_KAART_CODE_VALID;
0 голосов
/ 15 сентября 2018

Я бы переместил условие в сам запрос и поймал исключение NO_DATA_FOUND:

BEGIN
    SELECT * FROM CADEAUKAART WHERE kaart_code = :P10_KAART_CODE;
    RETURN TRUE;
EXCEPTION  WHEN NO_DATA_FOUND THEN
    RETURN FALSE;
END;
0 голосов
/ 15 сентября 2018

PL / SQL не поддерживает встроенный SQL в операторах if. Поэтому вам нужно переписать ваш код следующим образом:

create or replace function validate_kaart_code 
    (P10_KAART_CODE in CADEAUKAART.KAART_CODE%type)
    return boolean
is
    rv boolean;
    l_code CADEAUKAART.KAART_CODE%type;
BEGIN
    begin
        SELECT KAART_CODE into l_code
        FROM CADEAUKAART
        where KAART_CODE =:P10_KAART_CODE 
        and rownum = 1 -- only necessary if KAART_CODE is not unique
        ;
        rv := TRUE;
    exception
        when no_data_found then
            rv := FALSE;
    end;
    RETURN rv;
END;

Я попытался восстановить всю вашу функциональность из фрагмента, который вы разместили. Если это не то, что вы хотели, и вы не можете преобразовать его в соответствии со своими потребностями, пожалуйста, предоставьте более подробную информацию.

0 голосов
/ 15 сентября 2018

Вы можете попробовать курсор, в качестве альтернативы:

DECLARE
  v_flag  boolean := FALSE;  
BEGIN
 FOR c IN ( SELECT KAART_CODE FROM CADEAUKAART )
 LOOP
   IF :P10_KAART_CODE = c.KAART_CODE THEN
     v_flag := TRUE;
     EXIT;
   END IF;
  EXIT WHEN NO_DATA_FOUND;
 END LOOP;
     RETURN v_flag;
END;

Если вы не можете использовать оператор выбора, вы можете перечислить все члены для возвращаемых значений KAART_CODE, таких как

IF :P10_KAART_CODE IN ('aAA','BBb','ccC'..) THEN

но это не желательно и приятно перечислять все совпадающие значения.

...