ORACLE PL / SQL: функции и дополнительные параметры, как? - PullRequest
6 голосов
/ 19 октября 2010

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

Стандарт, с которым я работал в моемзадание таково:

FUNCTION get_records (
  i_code                                 IN records.code%type := NULL,
  i_type                                 IN records.type%type := NULL
) RETURN results

Проблема в том, что я хочу вернуть записи, которые также имеют тип NULL, и используя:

WHERE type = nvl(i_type, type)

Возвращает только записи с действительными типамиа не нулевые записи .. по понятным причинам.Мне просто интересно, есть ли стандартный способ сделать это, который мог бы быть реализован во всех функциях, которые мы используем.По совпадению, если я предоставлю параметр ... Я не хочу значения NULL этого поля.

Ответы [ 5 ]

5 голосов
/ 19 октября 2010

почему бы не просто то, что у вас есть с добавлением

 type = i_type OR (i_type IS NULL AND type IS NULL)

таким образом, когда переданное в параметре значение равно нулю, оно ищет все (включая нули) или указанное значение.Теперь, если вам нужен только пример с нулями ...

(измените значение с нуля на 5, и вы увидите результат)

WITH TESTDATA AS (
        SELECT LEVEL dataId
          FROM DUAL
         CONNECT BY LEVEL <= 100
        UNION
        SELECT NULL 
         from dual
)
SELECT * 
  FROM TESTDATA
 where dataId = :n or (:n is null AND dataId is null) ;

Тогда как: n = 6, результаты будутбыть

DATAID                 
---------------------- 
6

(удалил новое сообщение, неправильно прочитал параметр) Но мне нравится новый подход, и я избегаю NVL

Вот отличный способ сделать это, если вы не против динамическогоsql

http://www.oracle.com/technetwork/issue-archive/2009/09-jul/o49asktom-090487.html

4 голосов
/ 20 октября 2010

Стандартный способ решения этой проблемы - перегрузить функцию вместо использования значений по умолчанию:

FUNCTION get_records (
  i_code                                 IN records.code%type,
  i_type                                 IN records.type%type
) RETURN results;

FUNCTION get_records (
  i_code                                 IN records.code%type
) RETURN results;

FUNCTION get_records RETURN results;

Примечание. Если вам также нужна сама версия i_type, у вас могут возникнуть проблемы, если она имеет тот же базовый тип, что и i_code - в этом случае вам потребуется использовать другое имя для функции.

4 голосов
/ 19 октября 2010

С самого начала я думаю, что использование ключевого слова DEFAULT поможет, не так ли? (Следующая ссылка даст некоторые дополнительные сведения.)

  1. Использование ключевого слова ПО УМОЛЧАНИЮ .

    CREATE OR REPLACE FUNCTION get_records (
        i_code IN records.code%type DEFAULT NULL,
        i_type IN records.type%type DEFAULT NULL
    ) RETURN results
    

РЕДАКТИРОВАТЬ # 1

Если я правильно понял вопрос, вы хотите вернуть все записи, когда параметр i_type равен NULL. В отсутствие дальнейших подробностей мое предположение было бы следующим.

CREATE OR REPLACE FUNCTION get_records (
    i_code IN records.code%TYPE DEFAULT NULL,
    i_type IN records.type%TYPE DEFAULT NULL
) RETURN results
BEGIN
    IF (i_type IS NULL) THEN
        select *
            from table
    ELSE
        select *
            from table
            where type = NVL(i_type, type)
    END IF

    EXCEPTION
        WHEN OTHERS THEN
            NULL
END

Это все, что я могу сделать с предоставленной информацией, хотя текст функции приведен ниже.

РЕДАКТИРОВАТЬ # 2

Я немного заржавел от Oracle, поэтому я ознакомился с некоторыми документами, как показано ниже:

Oracle/PLSQL: NVL Function

Как я уже читал, вам лучше использовать функцию NVL в вашей инструкции SELECT, а не в предложении WHERE.

В конце концов, какой именно у вас вопрос? Не могли бы вы сделать это кристально чистым?

3 голосов
/ 19 октября 2010

Повторяю мое понимание проблемы: вы не можете принять значение по умолчанию NULL, означающее «вернуть все записи», потому что текущее ожидаемое поведение таково, что он будет возвращать только те записи, где значение фактически равно NULL..

Одна из возможностей - добавить логический параметр, соответствующий каждому параметру поиска, который указывает, должен ли он фактически использоваться для фильтрации результатов.Потенциальная проблема заключается в том, что вызывающая сторона может указать значение поиска, но не сможет установить флаг в значение true, что приведет к неожиданным результатам.Вы можете защититься от этого во время выполнения, вызвав исключение, если флаг имеет значение false для любого значения поиска, отличного от NULL.

Другая возможность - определить значение вне домена для каждого столбца поиска -Например, если для параметра передана строка «ЛЮБОЙ», она не будет фильтровать значения в этом столбце.Это должно работать нормально, если вы можете найти подходящее значение для каждого столбца.Я бы посоветовал объявить значения Sentry как константы в некотором пакете, чтобы вызовы функции могли выглядеть как get_records( PKG.ALL_CODES, 'type1' ).

1 голос
/ 26 ноября 2013

Я использовал следующий хак (предполагая, что p_product - необязательный ввод процедуры):

где t.product = decode (p_product, null, t.product, p_product)

procedure get_data(p_product in number := null)
...
select *
from tbl t
where t.product = decode(p_product, null, t.product, p_product);
...

Это создаст сценарий «где 1 = 1», когда продукт не передан, и использует продукт в противном случае.Один потенциально серьезный недостаток заключается в том, что он анализирует один и тот же план выполнения независимо от параметров.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...