결과 csv 문자열의 고유 값을 집계하여 csv 텍스트가있는 열에서 작동해야하는 간단한 집계 함수를 작성했습니다. 함수가 결과를 반환해야 할 때 ORA-06502 오류가 발생했을 때 함수가 끝까지 작동하는 것처럼 보입니다.오라클 plsql 집계 오류 : ORA-06502 : 문자열 버퍼가 너무 작습니다.
형 DEF : 여기
코드이다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
);
본체 :
SQL> desc uniontest
Name Null? Type
----------------------------------------- -------- ----------------------------
I NVARCHAR2(50)
SQL> select * from uniontest;
I
--------------------------------------------------
a
a
b,c
b,d,e
최종적 여기
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;
테스트 테이블 데이터 인 , 내가하려고하면이 일이 일어난다. 내가 단순히 잘못된 줄에 'X'와 같은 하나의 문자열을 전달하면 난 여전히 같은 오류가 발생,
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
: 집계 함수를 사용합니다. null 결과에서만 사라집니다. 나는 아이디어가 부족하다.
도움을 주셔서 감사합니다.
btw, 왜 누군가가 \ 0 문자를 추가했는지 알면, 나는 그것에 대해 알고 싶어 죽겠다. CONNECT BY
조건 행에 dependend되지 않기 때문에 내가 행의 무한이
SELECT DISTINCT(regexp_substr(orig, '[^,]+', 1, level)) AS a
FROM dual CONNECT BY regexp_substr(orig, '[^,]+', 1, level) IS NOT NULL ORDER BY a)
결과를 틀리지 않는 경우
이'nvarchar2'에 문제가 될 것으로 보인다
(... 여기
chr(0)
하고 문제의\0
는nvarchar2
관련이있는 것으로 보이지만, 다른 사람이 세부 사항에있는 칩해야합니다) 그것들이 단지'varchar2'로 변경되면 이것은 작동합니다. 내가하는 일보다는 내부적 인 것처럼 보이기 때문에 확실한 해결 방법을 볼 수 없습니다.대신 CLOB를 사용하여 무언가를 찢어 버릴 수도 있습니다. 또는 값을 다시 집계하고 구별 할 수있는 값을'listagg'에 전달하십시오. –