有没有办法确定pl_sql函数中输入参数的数据类型,就像我们在java中有 instanceof 一样。我尝试过使用dump函数,但它只能在查询中使用。
答案 0 :(得分:0)
从评论看来,您似乎希望通过循环输入参数来构建动态查询字符串,可能是为了构建where
子句而不必手动输入。这似乎会让维护和理解变得更难以获得更多好处。
但是,作为练习,您可以循环user_arguments
视图中的参数定义。问题是你无法在没有命名的情况下获得实际参数值,如果你这样做,那么数据类型只会在你将值直接放入动态字符串时才有意义(你可以'这真的是在一个循环中而不是作为绑定变量,无论如何这都是一件坏事。如果你正在使用绑定变量,那么你不需要知道数据类型。
因此,对于我自己的娱乐,如果我有一个包含各种数据类型的表:
create table t42(col1 varchar2(10), col2 number, col3 date);
insert into t42 values ('data', 42, trunc(sysdate));
...以及参数名称与表列名称匹配的函数,然后您可以使用绑定变量构建动态字符串:
create function f42(col1 t42.col1%type, col2 t42.col2%type,
col3 t42.col3%type)
return varchar2 is
str varchar(4000);
result t42.col1%type;
have_where boolean := false;
begin
str := 'select col1 from t42';
for r in (
select argument_name, data_type
from user_arguments
where object_name = 'F42'
and position > 0 -- to account for return type
order by position
) loop
if not have_where then
have_where := true;
str := str || ' where ';
else
str := str || ' and ';
end if;
str := str || r.argument_name || ' = :' || r.argument_name;
end loop;
dbms_output.put_line(str);
execute immediate str into result using col1, col2, col3;
return result;
end;
/
然后我可以从SQL * Plus调用它:
SQL> var rc varchar2(10);
SQL> exec :rc := f42('data', 42, trunc(sysdate));
select col1 from t42 where COL1 = :COL1 and COL2 = :COL2 and COL3 = :COL3
PL/SQL procedure successfully completed.
SQL> print rc
RC
--------------------------------
data
显然是一个非常人为的例子,但它可以扩展更多参数,只需要using
子句就可以列出所有参数。我认为。哪个不意味着我认为这是一个好主意 - 只是为了好玩......
如果需要,您可以根据数据类型在循环内进行一些操作,方法是检查r.data_type
值:
str := str || r.argument_name || ' = ';
if r.data_type = 'DATE' then
str := str || 'trunc(:' || r.argument_name || ')';
else
str := str || ':' || r.argument_name;
end if;
...然后你可以调用,而不必调用trunc
中的值:
SQL> exec :rc := f42('data', 42, sysdate);
select col1 from t42 where COL1 = :COL1 and COL2 = :COL2 and COL3 = trunc(:COL3)
PL/SQL procedure successfully completed.
SQL> print rc
RC
--------------------------------
data
...但除此之外,你不需要知道动态字符串中每列的类型,因为无论如何绑定都会处理它。