确定输入参数的数据类型

时间:2013-04-10 10:24:20

标签: oracle plsql

有没有办法确定pl_sql函数中输入参数的数据类型,就像我们在java中有 instanceof 一样。我尝试过使用dump函数,但它只能在查询中使用。

1 个答案:

答案 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

...但除此之外,你不需要知道动态字符串中每列的类型,因为无论如何绑定都会处理它。