SYS.STANDARD.ADD_MONTHS и просто ADD_MONTHS

Всё по теме СУБД Oracle: установка, настройка, использование, решение проблем и т.д. и т.п. и др. и пр.
Ответить
Аватара пользователя
SQL*Plus
Сообщения: 92
Зарегистрирован: Ср апр 20, 2022 1:09 pm

SYS.STANDARD.ADD_MONTHS и просто ADD_MONTHS

Сообщение SQL*Plus »

Столкнулся с интересным (странным?) эффектом при использовании функции ADD_MONTHS.

В спецификации пакета SYS.STANDARD увидел:

Код: Выделить всё

  function ADD_MONTHS(LEFT DATE, RIGHT NUMBER) return DATE;
    pragma BUILTIN('ADD_MONTHS',39, 12, 13); -- PEMS_DATE, DATE_ADD_MONTHS1
    pragma FIPSFLAG('ADD_MONTHS', 1450);
  function ADD_MONTHS(LEFT NUMBER, RIGHT DATE) return DATE;
    pragma BUILTIN('ADD_MONTHS',39, 12, 14); -- PEMS_DATE, DATE_ADD_MONTHS2
    pragma FIPSFLAG('ADD_MONTHS', 1450);
То есть вроде бы можно два обязательных аргумента функции перечислять в любом порядке,
а по их типу Oracle уже разберется какую конкретную функцию вызывать.

Пробуем:

Код: Выделить всё

SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY';
Session altered.

SQL> select sys.standard.add_months(DATE '2001-01-01', 1) Date_and_nmon 
  2       , sys.standard.add_months(1, DATE '2001-01-01') nmon_and_date 
  3       , version
  4  from v$instance;

DATE_AND_NM NMON_AND_DA VERSION          
----------- ----------- -----------------
01-ФЕВ-2001 01-ФЕВ-2001 19.0.0.0.0  
Получилось! Можно и так и сяк!

Теперь уберем при вызове полную спецификацию sys.standard.:

Код: Выделить всё

SQL> select add_months(DATE '2001-01-01', 1) Date_and_nmon 
  2       , add_months(1, DATE '2001-01-01') nmon_and_date 
  3       , version
  4  from v$instance;

Error starting at line : 20 in command -
select add_months(DATE '2001-01-01', 1) Date_and_nmon 
     , add_months(1, DATE '2001-01-01') nmon_and_date 
     , version
from v$instance
Error at Command Line : 21 Column : 19
Error report -
SQL Error: ORA-00932: несовместимые типы данных: ожидается DATE, получено NUMBER
00932. 00000 -  "inconsistent datatypes: expected %s got %s"
Получили ошибку. :-(
Аватара пользователя
SQL*Plus
Сообщения: 92
Зарегистрирован: Ср апр 20, 2022 1:09 pm

Re: SYS.STANDARD.ADD_MONTHS и просто ADD_MONTHS

Сообщение SQL*Plus »

Исправляем ошибку, добавляя SYS.STANDARD. ко второму (недокументированному) варианту вызова функции:

Код: Выделить всё

SQL> select add_months(DATE '2001-01-01', 1) Date_and_nmon 
  2       , SYS.STANDARD.add_months(1, DATE '2001-01-01') nmon_and_date 
  3       , version
  4  from v$instance;

DATE_AND_NM NMON_AND_DA VERSION          
----------- ----------- -----------------
01-ФЕВ-2001 01-ФЕВ-2001 19.0.0.0.0       
Работает!

Вопрос:
Работают разные варианты функции?
ADD_MONTHS - встроенная функция языка SQL
и
SYS.STANDARD.ADD_MONTHS - встроенная функция языка PL/SQL

Или как?
Ответить