我遇到了一种情况,其中函数参数的类型正确,但数据库无法识别它。
简化模型:
-- Создам таблицу для экспериментов
create table my_table (a varchar2(1000));
/
-- Создам заголовок пакета
create or replace package my_pkg as
type my_type is table of varchar2(1000) index by varchar2(1000);
function my_func (p_input my_type) return varchar2;
procedure my_proc;
end my_pkg;
/
-- Создам тело пакета
create or replace package body my_pkg as
function my_func (p_input my_type) return varchar2 is
begin
if p_input is null
then return null;
else return p_input(p_input.first);
end if;
end;
procedure my_proc is
v_val my_type;
begin
v_val('Hello,') := ' world!';
v_val('How') := ' do you do?';
insert into my_table (a) values (my_func(v_val));
--dbms_output.put_line(my_func(v_val));
commit;
end;
end my_pkg;
/
在这段代码中,编译器会发誓使用v_val以下行:
insert into my_table (a) values (my_func('aga',v_val));
使用错误文本(光标设置为v_val):
错误:PLS-00382:表达式类型错误 行:17 文本:插入 my_table (a) values(my_func(v_val));
在这种情况下,如果将注释移到insert并从中释放,则该行:
dbms_output.put_line(my_func('aga',v_val));
不会发生错误。虽然,很明显,该函数被使用并且相同的参数被传递给它。
可能是什么问题呢?
两行的差异,第一行会出错,第二行会起作用:
第一个将被发送到 SQL 解析器,第二个将被编译成 PL/SQL。
向解析器发送 SQL 语句时,PL/SQL 编译器必须确保在运行时它可以传递所有绑定变量,其数据类型要么在 SQL 上下文中已知,要么可隐式转换为 SQL 数据类型。
数据类型是关联集合,这是 PL/SQL 数据类型的主要示例,它在 SQL 上下文中没有可以转换为的类型。
来自评论:
如果该函数未在包规范中声明,即在 SQL 上下文中根本不知道,则会发生此错误。
解决方案是不在可在 SQL 上下文中调用的函数中使用 PL/SQL 数据类型参数。例如: