0

結果のcsv文字列の個別の値を集計することにより、csvテキストを含む列で機能する単純な集計関数を作成しました。結果を返す必要があるときにORA-06502エラーが発生すると、関数は最後まで機能するようです。

コードは次のとおりです。

タイプ定義:

create or replace type array_union_typ as object (

union_agg nvarchar2(1000),

static function ODCIAggregateInitialize(sctx  in out array_union_typ)
                return number,

member function ODCIAggregateIterate   (self  in out array_union_typ,
                                        value in nvarchar2)
                return number,

member function ODCIAggregateTerminate (self         in array_union_typ,
                                        return_value out nvarchar2,
                                        flags        in number)
                return number,

member function ODCIAggregateMerge(self in out array_union_typ,
                                   ctx2 in array_union_typ)
                return number,

static function agg_union(arg1 in nvarchar2,
                          arg2 in nvarchar2)
                return nvarchar2
);

本体:

create or replace type body array_union_typ  is

static function ODCIAggregateInitialize(sctx in out array_union_typ
                                     ) return number is
begin
    sctx := array_union_typ(null);
    return ODCIConst.Success;
end;

member function ODCIAggregateIterate(self in out array_union_typ,
                                     value in nvarchar2
                                     ) return number is
begin
    union_agg := array_union_typ.agg_union(union_agg, value);
    return ODCIConst.Success;
end;

member function ODCIAggregateTerminate(self in array_union_typ,
                                       return_value out nvarchar2,
                                       flags in number
                                       ) return number is
begin
    dbms_output.put_line('result: '''|| union_agg || ''', length:' || length(union_agg)); --this still prints
    return_value := self.union_agg; -- <-- this is where the error is indicated
    --return_value := 'x'; -- returning this still gives the error.
    return ODCIConst.Success;
end;

member function ODCIAggregateMerge(self in out array_union_typ,
                                   ctx2 in array_union_typ
                                   ) return number is
begin
    union_agg := array_union_typ.agg_union(union_agg, ctx2.union_agg);
    return ODCIConst.Success;
end;

static function agg_union(arg1 in nvarchar2,
                          arg2 in nvarchar2)
                return nvarchar2 is
    result nvarchar2(1000);
    orig nvarchar2(1000);
begin
    dbms_output.enable;
    orig := replace(arg1||','||arg2, chr(0));

    FOR rec IN (SELECT DISTINCT(regexp_substr(orig, '[^,]+', 1, level)) AS a
           FROM dual CONNECT BY regexp_substr(orig, '[^,]+', 1, level) IS NOT NULL ORDER BY a) LOOP
      IF result IS NOT NULL THEN
        result := result || ',' || rec.a;
      ELSE
        result := rec.a;
      END IF;
    END LOOP;
    --dbms_output.put_line('endwith: ''' || result || '''');
    RETURN substr(result,1,1000);
end;
end;

テストテーブルとデータは次のとおりです。

SQL> desc uniontest
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 I                                                  NVARCHAR2(50)

SQL> select * from uniontest;

I
--------------------------------------------------
a
a
b,c
b,d,e

最後に、集計関数を使用しようとすると、次のようになります。

SQL> select array_union(i) from uniontest;
select array_union(i) from uniontest
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "M35456.ARRAY_UNION_TYP", line 25


result: 'a,b,c,d,e', length:9

問題のある行に「x」のような単一の文字列を渡すだけでも、同じエラーが発生します。結果が null の場合にのみ消えます。私は困惑していて、アイデアがありません。

助けてくれてありがとう。

ところで、\0 文字が agg_union 関数のパラメータに追加される理由を誰かが知っている場合は、それについても知りたいと思っています。

4

2 に答える 2

0

私が間違っていなければ、これ

 SELECT DISTINCT(regexp_substr(orig, '[^,]+', 1, level)) AS a
       FROM dual CONNECT BY regexp_substr(orig, '[^,]+', 1, level) IS NOT NULL ORDER BY a) 

CONNECT BY条件は行に依存しないため、行の数は無限になります。

結果をループして文字列に文字を追加するため、文字列がすぐに大きくなります。

于 2012-05-16T04:46:49.950 に答える