Значения по умолчанию в функциях Oracle

Предположим следующее объявление функции:

FUNCTION ARTTEXTJN
(p_art_id     in number
,p_arttextart in varchar2 default 'basis'
,p_sprache    in varchar2 default null
,p_aufart     in number   default null
,p_fallback_arttextart in varchar2  default 'J' 
)
RETURN VARCHAR2

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

jOOQ генерирует такой метод пакета:

public static Field<String> arttextjn(Field<? extends Number> pArtId, Field<String> pArttextart, 
              Field<String> pSprache, Field<? extends Number> pAufart, Field<String> pFallbackArttextart) {
    Arttextjn f = new Arttextjn();
    f.setPArtId(pArtId);
    f.setPArttextart(pArttextart);
    f.setPSprache(pSprache);
    f.setPAufart(pAufart);
    f.setPFallbackArttextart(pFallbackArttextart);
    return f.asField();
}

Если я хочу использовать его в запросе, я должен передать значение null в функцию:

dsl.select(KAMPARTIKEL.ARTNR, KAMPARTIKEL.ARTNRKAMP,
           PaBez.arttextjn(KAMPARTIKEL.ART_ID, null, null, null, null))

Но тогда Oracle не использует значения по умолчанию.

Есть ли способ заставить jOOQ генерировать перегруженные методы со всеми возможными комбинациями? В противном случае я не могу использовать эту функцию в предложении select.


person Simon Martinelli    schedule 23.04.2019    source источник


Ответы (1)


Есть ли способ заставить jOOQ генерировать перегруженные методы со всеми возможными комбинациями?

Нет, комбинаций было бы слишком много. Конечно, вы можете расширить генератор кода самостоятельно, но я бы не советовал этого делать.

В противном случае я не могу использовать эту функцию в предложении select.

Да, вы можете использовать его! Но не используя этот вспомогательный метод PaBez.arttextjn. Его можно вызвать как отдельный вызов функции:

Arttextjn f = new Arttextjn();
f.setPArtId(1);
f.execute();
String result = f.getReturnValue();

Должна быть возможность использовать и в операторе SQL:

Arttextjn f = new Arttextjn();
f.setPArtId(KAMPARTIKEL.ART_ID);

var result =
dsl.select(KAMPARTIKEL.ARTNR, KAMPARTIKEL.ARTNRKAMP, f.asField())
   .from(KAMPARTIKEL)
   .fetch();

В вашем случае это должно работать из коробки.

Обратите внимание, что начиная с jOOQ 3.11 и в Oracle jOOQ в данном случае передает аргументы функции по индексу, а не по имени (как в PostgreSQL). Сгенерированный SQL:

select KAMPARTIKEL.ARTNR, KAMPARTIKEL.ARTNRKAMP, pa_bez.arttextjn(KAMPARTIKEL.ART_ID)
from KAMPARTIKEL

Что работает, потому что вы используете только первый параметр, применяя значения по умолчанию для остальных. Это не сработает, если вы передадите последний параметр, в случае чего сгенерированный SQL должен будет использовать именованные параметры:

select 
  KAMPARTIKEL.ARTNR, 
  KAMPARTIKEL.ARTNRKAMP, 
  pa_bez.arttextjn(p_art_id => KAMPARTIKEL.ART_ID)
from KAMPARTIKEL

Я создал проблему, чтобы исправить это для jOOQ 3.12: https://github.com/jOOQ/jOOQ/issues/8560

person Lukas Eder    schedule 23.04.2019
comment
Спасибо, это уже решает нашу проблему, потому что мы обычно используем первые параметры, но версия от 3.12 будет еще лучше! - person Simon Martinelli; 23.04.2019
comment
Как правило, при перегрузке метода с необязательными параметрами вместо него можно объявить несколько методов, каждый из которых имеет крайние правые необязательные параметры. Для параметров n, где все параметры, кроме первого, являются необязательными, первый метод имеет один необязательный параметр (самый правый), следующий метод имеет два необязательных параметра (самые правые два) и т. д. всего n - 1 перегруженных методов. Это уменьшает количество комбинаций перегруженных методов. - person David R Tribble; 23.04.2019
comment
@DavidRTribble: Спасибо за просвещение. Я не думаю, что имеет смысл создавать перегруженные методы в jOOQ API, как вы предлагаете. В общем, в PL/SQL именованные параметры и параметры по умолчанию часто используются так же, как вы использовали бы карту или свойства в Java. По моему опыту, предположение о том, что большинство правильных параметров со значительно большей вероятностью будут опущены, неверно. YMMV, конечно. - person Lukas Eder; 23.04.2019