Как передать NULL в перегруженную функцию? PLS-00307: Слишком много описаний 'MY_FUNC' соответствующих этому вызову

У меня есть несколько перегруженных функций в пакете. Например:

function my_func(i_val varchar2) return varchar2 is
begin
  return '!' || i_val || '!';
end;

function my_func(i_val number) return varchar2 is
begin
  return to_char(i_val+1);
end;

И всё замечательно до тех пор, пока мы передаем значения, отличные от NULL. И даже NULL мы можем передать, если заранее присвоим его в переменную. То есть рабочим будет код:

declare
  a number;
  b varchar2(32767);
begin
  b := my_pkg.my_func(i_val => a);
end;

Но если мы передадим скаляр, равный NULL:

declare
  b varchar2(32767);
begin
  b := my_pkg.my_func(i_val => null);
end;

То поймаем ошибку:

PLS-00307: Слишком много описаний 'MY_FUNC' соответствующих этому вызову

Можно ли как-то исключить эту ситуацию? Например, явно задав, какую функцию вызывать в таком случае.


Ответы (1 шт):

Автор решения: 0xdb

У литерала NULL нет конкретного типа данных, это «ничто».

В PL/SQL, в отличии от SQL, литерал NULL не приводится по умолчанию к VARCHAR2, поэтому надо подсказать компилятору, какой тип данных подразумевается.

Например явно (рекомендуемо):

var ret varchar2 (8)
exec :ret := pack.func (cast (null as varchar2))

RET
---
!!

Или более короткими подсказками:

exec :ret := pack.func (''||null)

RET
---
!!

exec :ret := pack.func (0+null)

RET
----
null
→ Ссылка