programing

Listagg 함수 및 ORA-01489: 문자열 연결 결과가 너무 깁니다.

closeapi 2023. 10. 13. 22:15
반응형

Listagg 함수 및 ORA-01489: 문자열 연결 결과가 너무 깁니다.

다음 쿼리를 실행할 때:

 Select
  tm.product_id,
  listagg(tm.book_id || '(' || tm.score || ')',',')
    within group (order by tm.product_id) as matches
from
  tl_product_match tm 
where
  tm.book_id is not null 
group by
  tm.product_id

Oracle은 다음 오류를 반환합니다.

 ORA-01489: result of string concatenation is too long

listagg 함수가 지원되지 않는 4000자 이상의 값을 연결하려고 하기 때문에 실패하는 것으로 알고 있습니다.

여기에 설명된 http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php 이라는 대안적인 예를 보았지만 모두 기능이나 절차를 사용해야 합니다.

함수나 저장 프로시저를 호출하지 않고 표준 JDBC를 사용하여 값을 읽을 수 있는 순수 SQL 솔루션이 있습니까?

또 다른 어려움은 제가 본 대부분의 문자열 집계 예제가 값을 그대로 읽는 방법에 대한 예제를 보여준다는 것입니다.에 대한 예제에서는 값을 먼저 수정하고 있습니다(즉, 두 개의 열을 집계하고 있습니다).

xml 함수를 사용하여 CLOB를 반환하는 작업을 수행할 수 있습니다. JDBC는 그것으로 충분할 것입니다.

select tm.product_id, 
       rtrim(extract(xmlagg(xmlelement(e, tm.book_id || '(' || tm.score || '),')), 
               '/E/text()').getclobval(), ',')
  from tl_product_match tm
 where tm.book_id is not null 
 group by tm.product_id;

예: http://sqlfiddle.com/ #!4/083a2/1

중첩 테이블을 사용하지 않는 이유는 무엇입니까?

set echo on;
set display on;
set linesize 200;

drop table testA;
create table testA
(
col1 number,
col2 varchar2(50)
);

drop table testB;
create table testB
(
col1 number,
col2 varchar2(50)
);

create or replace type t_vchar_tab as table of varchar2(50);

insert into testA values (1,'A');
insert into testA values (2,'B');

insert into testB values (1,'X');
insert into testB values (1,'Y');
insert into testB values (1,'Z');
commit;

-- select all related testB.col2 values in a nested table for each testA.col1 value
select a.col1, 
cast(multiset(select b.col2 from testB b where b.col1 = a.col1 order by b.col2) as t_vchar_tab) as testB_vals
from testA a;

-- test size > 4000
insert into testB
select 2 as col1, substr((object_name || object_type), 1, 50) as col2
from all_objects;
commit;

-- select all related testB.col2 values in a nested table for each testA.col1 value
select a.col1, 
cast(multiset(select b.col2 from testB b where b.col1 = a.col1 order by b.col2) as t_vchar_tab) as testB_vals
from testA a;

저는 자바 전문가는 아니지만, 이것은 꽤 오래전부터 있어왔고 자바는 내포된 테이블에서 값을 끌어낼 수 있을 것이라고 확신합니다.그리고 다른 쪽 끝에 구분된 문자열을 토큰화할 필요가 없습니다.

여기에 설명된 http://www.oracle-base.com/articles/misc/string-aggregation-techniques.php 이라는 대안적인 예를 보았지만 모두 기능이나 절차를 사용해야 합니다.

아니, 그들은 하지 않아.아래로 스크롤하면 pl/sql이 필요 없는 여러 옵션이 표시됩니다.

처음 4,000자만 원하는 경우 버전 12.2 이후의 함수에는 오버플로 데이터를 쉽게 잘라내고 생략법을 추가한 다음 잘라낸 값의 수를 추가하는 옵션이 있습니다.

select owner, listagg(object_name, ',' on overflow truncate) within group (order by object_name) names
from all_objects
group by owner
order by owner;

OWNER   NAMES
-----  ------
SYS    ACCESS$,ACLMV$,[hundreds of names here],ALL_GOLDENGATE_RULES,...(47742)

언급URL : https://stackoverflow.com/questions/14864055/listagg-function-and-ora-01489-result-of-string-concatenation-is-too-long

반응형