PLSQL: условно применить проверку оператора IN

Пользователь вводит числа (1,2,3 и т.д.). Мое требование состоит в том, что если номер ввода пользователя присутствует в таблице базы данных, то должны быть получены только эти записи. Если пользователь НЕ ввел данные, то должны быть извлечены ВСЕ записи из таблицы.

Вводимые пользователем числа хранятся в table type, а соответствующий код приведен ниже.

CREATE OR REPLACE TYPE ACCNT_NUMBER_TYPE AS TABLE OF NUMBER; //ACCNT_NUMBER_TYPE будет иметь значения 1,2,3 и т. д.

Ниже моя процедура.

CREATE OR REPLACE PACKAGE BODY pr_retrieve_data as
PROCEDURE FETCH_MYTABLE_DETAILS() is

FOR indx in (select column1,
                    column2
             from   SOMEOTHERTABLE SOT
             WHERE  SOT.ACCNT_NUMBER IN (SELECT * FROM TABLE(L_ACCNT_NUMBER)))
LOOP

...
-- Around 300 lines of code goes here

END LOOP;

end FETCH_MYTABLE_DETAILS;
end pr_retrieve_data;

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

Я мог бы написать еще один цикл FOR, поставив условие, если данные пользователя равны null. Но будет повторение 300 строк кода. Это увеличит техническое обслуживание.

Как настроить цикл FOR таким образом, чтобы, если пользователь вводит данные, извлекалась только эта запись, а когда пользователь не ввел данные, извлекались ВСЕ записи?


person user2488578    schedule 22.02.2019    source источник


Ответы (2)


Похоже, что переменная инициализирована и заполнена нулями. Проверьте, есть ли в l_accnt_number какие-либо ненулевые значения, и создайте условие цикла, как здесь:

... 
procedure fetch_mytable_details() is
  l_accnt_not_null number(6);
begin
  select count(1) 
    into l_accnt_not_null 
    from table(l_accnt_number) 
    where column_value is not null;

  for indx in (select  column1, column2
                 from  someothertable sot
                 where l_accnt_not_null = 0 
                    or sot.accnt_number in (select * from table(l_accnt_number)))
...
person Ponder Stibbons    schedule 22.02.2019
comment
Да, вы угадали. Переменная была инициализирована и заполнена null. Может быть, поэтому решение, предоставленное @Gordon, не сработало. - person user2488578; 22.02.2019

Я думаю, вы хотите not exists:

select column1, column2
from SOMEOTHERTABLE SOT
where SOT.ACCNT_NUMBER in (select * from TABLE(L_ACCNT_NUMBER)) or
      not exists (select 1 from TABLE(L_ACCNT_NUMBER));

Это вернет все строки во внешнем запросе, если в таблице входных данных нет строк.

person Gordon Linoff    schedule 22.02.2019
comment
Это не сработало. Если пользователь не вводит данные, то с указанным выше условием not exists я НЕ получаю все записи. - person user2488578; 22.02.2019
comment
Насколько я могу судить, вы должны. Вопрос Гордона выглядит нормально для меня. - person Littlefoot; 22.02.2019
comment
@Littlefoot @Gordon: я думаю, что это решение работает, если переменная не имеет значений null. В любом случае, я проголосовал. Решение, предоставленное @Ponder, сработало для меня. - person user2488578; 22.02.2019