【问题标题】:How can I use bind variable in plsql function如何在 plsql 函数中使用绑定变量
【发布时间】:2018-06-01 15:11:53
【问题描述】:

我有这样的功能:

create or replace function params
(
    p_pr     varchar2,
    p_qu_id  varchar2,
    p_date   date := sysdate,
    p_param  varchar2 := null
)
    return   varchar2
as
    ...
    sql_stmt varchar2(4000);
    rc       sys_refcursor;
    ...
BEGIN
    sql_stmt := 'select parameter_name, parameter_value from ' || p_pr | '.v_view where query_id = ''' || p_qu_id || '''';

    IF p_param IS NOT NULL
    THEN
        sql_stmt := sql_stmt || ' and parameter_value=''' || p_param || '''';
    END IF;

    OPEN rc FOR sql_stmt;
    LOOP
        FETCH rc
            INTO v_param_name, v_param_value;
        EXIT WHEN rc%NOTFOUND;
        EXIT WHEN v_param_value is NULL;

        ....

DBA 说这个函数使用硬解析,我必须在这个函数中使用绑定变量。我该怎么做?

谢谢。

【问题讨论】:

  • 您在这里缺少管道:... from ' || p_pr |。您将无法将 p_pr 变量绑定到查询中,因为它是表名的一部分,但您可以使用 dbms_assert 来确保它符合有效标识符名称的条件。不过,您可以绑定 parameter_value 并打开传入 p_param 值的游标。 See here 的示例说明如何做到这一点。

标签: oracle plsql bind-variables


【解决方案1】:

我必须在这个函数中使用绑定变量。

解决方法是在模板SQL中使用占位符...

sql_stmt := sql_stmt || ' and parameter_value= :p1';

...然后在打开引用游标时使用 USING 子句传递实际值。

事情有点棘手,因为您正在执行不同的语句,具体取决于是否填充了参数。所以你需要做这样的事情:

sql_stmt := 'select parameter_name, parameter_value from ' || p_pr 
     || '.v_view where query_id =:p1';

IF p_param IS NOT NULL
THEN
    sql_stmt := sql_stmt || ' and parameter_value= :p2';
    OPEN rc FOR sql_stmt using p_qu_id, p_param;
else
   OPEN rc FOR sql_stmt using p_qu_id;
END IF;

LOOP

请注意,p_pr - 模式名称 - 不能用绑定变量替换。

【讨论】:

  • 条件绑定看起来像以下之一:oracle.com/technetwork/issue-archive/2009/09-jul/…
  • @williamrobertson - 是的,这是另一种方式。我的感觉是,也许我们真的有两个不同的疑问。重写代码以使用绑定变量与重写代码以仅执行一个查询而不管我们传递什么参数是有区别的。我发现我的版本更容易理解,尽管如果过程传递大量可选参数会变得混乱。 (尽管这是一个架构问题。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多