Проблема нулевого значения PL / SQL в запросе - PullRequest
1 голос
/ 07 июля 2011

Мне нужно создать функцию pl / sql, которая принимает семь входных параметров.

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

Есть ли способ сделать это без использования количества вложенных ifs для проверки нулевых значений?

Ответы [ 4 ]

3 голосов
/ 07 июля 2011

Также необходимо проверить, что входные параметры равны нулю или нет в предложении WHERE

Например, предположим, что входные параметры - это параметр1, параметр2, параметр3

select * from tableA
where (col1 = parameter1 or parameter1  is null)
and (col2 = parameter2 or parameter2  is null)
and (col3 = parameter3 or parameter3  is null)

Если параметр1 равен нулю, он всегда будет возвращать true для условия этого параметра.

2 голосов
/ 07 июля 2011

Вы можете использовать

select * from table t where 
(param1 is null or t.column1 = param1) and 
(param2 ....)

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

Чтобы получить лучшее решение, вы должны использовать динамический запрос.В PLSQL это делается с использованием execute immediate l_query; (or open cursor for l_query;) для большинства ситуаций или с помощью более мощного (но гораздо более сложного в использовании) DBMS_SQL (требуется в очень ограниченном количестве случаев).

Проще (но с использованием литералов и, следовательно, поэтомутребуется жесткий анализ практически каждый раз, когда он запускается) решение

procedure dynamic_query_literals (param1 ... param7)
is
  l_query varchar2(1000);
  l_cursor sys_refcursor;
begin
  l_query := 'select * from table t where 1=1';
if (param1 is not null) then 
  l_query := l_query || ' and t.column1 = param1';
end if;
if (param2 ...)
  open l_cursor for l_query;

  -- do whatever needed with the result set in the cursor. 
  --The procedure can even return this cursor...
end;

Более сложное, но более производительное (особенно если эта процедура вызывается МНОГИЕ раз), решение требует привязки параметров (что выполняется автоматически и прозрачно, когдавы используете статический sql в plsql)

procedure dynamic_query_binding (param1 ... param7)
is
  l_query varchar2(1000);
  l_cursor sys_refcursor;
begin
  l_query := 'select * from table t where 1=1';

if (param1 is null) then 
  --this will get optimised away in the process but is required 
  --syntactically for use of "using" later
  l_query := l_query || ' and 1=1 or :param1 is null';
else
  l_query := l_query || ' and t.column1 = :param1';
end if;

if (param2 ...)

open l_cursor for l_query
using param1, param2, ... param7;

  -- do whatever needed with the result set in the cursor. 
  -- The procedure can even return this cursor...
end;

Эта версия будет использовать индексы в таблице соответствующим образом и все еще получит только один жесткий анализ на уникальную комбинацию «обнуляемых» параметров.

Недостатком обеих динамических версий является то, что вы не получаете проверку синтаксиса во время компиляции.

2 голосов
/ 07 июля 2011

1 решение заключается в использовании логики в предложении where для короткого замыкания условий

например:

SELECT blah WHERE (param1 IS NOT NULL AND col1=param1)
     OR (param2 IS NOT NULL AND col2=param2) ….etc

Примечание: без параметров = без результатов

или

    SELECT blah WHERE (param1 IS NULL OR col1=param1)
     AND (param2 IS NULL OR col2=param2) ….etc

Примечание: без параметров = все результаты

0 голосов
/ 07 марта 2017

Вы можете использовать следующее:

select * from tableA
where col1 = nvl(parameter1, col1) 
and ....
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...