1

用の動的 SQL ステートメントを作成するときに、文字列連結の代わりにバインド変数を使用したいと考えていますexecute immediate

a以下の例では、bとのバインド変数を使用できますがret、バインドしようとするfORA-06502: PL/SQL: numeric or value error: character to number conversion error. なぜ、どのように私もバインドできるのfですか?

11.2.0.1.0 を使用しています。

create or replace function so4fun (
  a in number, 
  b in number,
  f in varchar2
) return number as
  decl constant varchar2(32767) := 
    'declare a constant number := :a; b constant number := :b;';
  stmt varchar2(32676);
  ret number;
begin
  /* This one works: */
  stmt := decl || ' begin :result := ' || f || '; end;';
  execute immediate stmt using in a, in b, out ret;

  /* But why this one doesn't ?

  stmt := decl || ' begin :result := :f; end;';
  execute immediate stmt using in a, in b, out ret, in f;

  This doesn't work either:

  stmt := decl || ' tmp number; begin tmp := :f; :result := tmp; end;';
  execute immediate stmt using in a, in b, in f, out ret;

  Both are giving me ORA-06502: PL/SQL: numeric or value error: character to
  number conversion error */

  return ret;
end;
/
show errors

/* expected result when a = 1, b = 2 is 1.5 */
select so4fun(1, 2, '(a + b) / b') from dual;

drop function so4fun;
4

2 に答える 2

2

バインド変数は、コードの一部をバインドするためではなく、変数をバインドするためのものです。アイデアは、Oracle がクエリまたはコードのブロックをコンパイルおよびキャッシュし、さまざまなパラメーターを使用して複数回実行できるというものです。

ただし、計算された数式を置き換えるためにパラメーター バインディングを使用しようとします。コード ブロックのコンパイルとキャッシュが妨げられるため、サポートされていません。

また、現在の構文では表現できません。オラクルが見れば、パラメータを変数tmp := :fに割り当てたいだけだと考えます。関数を評価する必要はありません。ftmp

実用的なソリューションを使用してください。結局、それは機能します。

于 2011-08-02T05:54:52.020 に答える
1

fとして宣言したvarchar2が、コメントアウトされたセクションに次のように記述したため、エラーが発生します。

tmp number; begin tmp := :f ...

数値を期待する変数に「文字」値を代入しようとする場合。fまた、数値を期待する関数結果に代入しようとしました。

||それは文字列連結であるため、問題なく動作します。

どうにかして varchar2 を数値 ( ) に変換するか、変数を varchar2 ではなく数値としてTO_NUMBER(f)受け入れるように proc を記述する必要があります。f

于 2011-08-02T05:35:13.453 に答える