0

有什么方法可以确定pl_sql 函数中输入参数的数据类型,就像我们在 java 中有instanceof一样。我尝试过使用转储功能,但它只能在查询中使用。

4

1 回答 1

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

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

于 2013-04-10T11:42:56.220 回答