0

動的 SQL を使用する小さな関数があります。ストアド プロシージャの実行時に Viewname と Where_clause を取得するため、動的 SQL も必要です。

create or replace FUNCTION Costs_MK(VIEWNAME     IN VARCHAR2,
                                    WHERE_Clause IN VARCHAR2)
RETURN VARCHAR2
IS
  v_Costs VARCHAR2(3000);
BEGIN
  EXECUTE IMMEDIATE 'Select Listagg(Costs, ' || '''' || ';' || '''' || ' )
                     WITHIN GROUP (ORDER BY Costs)
                       from (select distinct (Costs)
                       from ' || Viewname || ' where ' || where_Clause || ')'
  INTO v_Costs;

  dbms_output.put_line(length(v_Costs));

  RETURN v_Costs;
END Costs_MK;

出力:

ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: in Line 9
1600

変数 v_Costs の長さは 1600 で、既に長さを 3000 に設定しています。ただし、毎回このエラーが発生し、これを解決するために何ができるかわかりません。

行 9 は次のとおりです。

Line 8: BEGIN
Line 9:
Line 10:   EXECUTE IMMEDIATE

匿名ブロック:

DECLARE
  VIEWNAME VARCHAR2(200);
  WHERE_Clause VARCHAR2(200);
  v_Return VARCHAR2(200);
BEGIN
  VIEWNAME := 'Orders';
  WHERE_BEDINGUNG := 'Orders.key like ' || '''' || '  B01  230/01/123456%' || '''';

  v_Return := Costs_MK(
    VIEWNAME => VIEWNAME,
    WHERE_Clause => WHERE_Clause
  );

  /* Legacy output:
     DBMS_OUTPUT.PUT_LINE('v_Return = ' || v_Return);
   */
  :v_Return := v_Return;

  --rollback;
END;

そして今、私はエラーを見つけました。は 200 しかないためv_Return VARCHAR2(200)です。たとえば 4000 に上げると、目的の結果が得られます。さて、私はこれを解決する方法を知っていると思います。

4

2 に答える 2

2

からの出力が表示されます

dbms_output.put_line(length(v_Costs));

...そのため、関数はそのポイントに到達しているため、9 行目 (空の行) またはその出力が生成される前の他の場所で例外をスローしていません。

したがって、例外を受け取っているのは呼び出し元である必要があります。関数を呼び出すプロシージャ、またはプロシージャを呼び出す無名ブロックのいずれかです。しかし、機能そのものではありません。

示されている例外スタックに基づいて、それは無名ブロックから来ています。これは、プロシージャ名も関数名もそのスタックにないためです (ただし、プロシージャ名を省略した可能性はあります)。無名ブロックの 9 行目は、変数には長すぎる値を代入している必要がありますが、返された数値を文字列に追加していて、それが長すぎる場合を除き、関数とは関係ありません。

あなたの匿名ブロックはこれを行っています:

DECLARE
  ...
  v_Return VARCHAR2(200);
BEGIN
  ...
  v_Return := Costs_MK(
    VIEWNAME => VIEWNAME,
    WHERE_Clause => WHERE_Clause
  );

したがって、9 行目では、1600 文字の値であることがわかっている値を、200 文字として宣言した変数に代入しようとしています。したがって、エラー。の宣言を変更してv_Return、関数変数のサイズに合わせます (または、両方を 4000 にして、オーバーヘッドを増やします)。

于 2015-08-10T14:21:46.780 に答える
0

4000まで拡張v_Costsしてみてください。それでもエラーが発生する場合は、LISTAGG によって生成された文字列が 4000 (VARCHAR2 の最大長) を超えていることが問題です。

それが問題である場合は、XMLAGG またはこの質問で提供されているソリューションの 1 つを使用する必要があります: How to tweak LISTAGG to support more than 4000 character in select query?

于 2015-08-10T13:52:37.203 に答える