[英]Listagg Overflow function implementation (Oracle SQL)
I am using LISTAGG
function for my query, however, it returned an ORA-01489: result of string concatenation is too long
error. 我正在使用LISTAGG
函数进行查询,但是返回了ORA-01489: result of string concatenation is too long
错误。 So I googled that error and found out I can use ON OVERFLOW TRUNCATE
and I implemented that into my SQL but now it generates missing right parenthesis
error and I can't seem to figure out why? 因此,我搜索了该错误,发现可以在ON OVERFLOW TRUNCATE
使用,并在SQL中实现了该功能,但是现在它会生成missing right parenthesis
错误,我似乎无法弄清楚为什么?
My query 我的查询
SELECT DISTINCT cust_id, acct_no, state, language_indicator, billing_system, market_code,
EMAIL_ADDR, DATE_OF_CHANGE, TO_CHAR(DATE_LOADED, 'DD-MM-YYYY') DATE_LOADED,
(SELECT LISTAGG( SUBSTR(mtn, 7, 4),'<br>' ON OVERFLOW TRUNCATE '***' )
WITHIN GROUP (ORDER BY cust_id || acct_no) mtnlist
FROM process.feature WHERE date_loaded BETWEEN TO_DATE('02-08-2018','MM-dd-yyyy')
AND TO_DATE('02-09-2018', 'MM-dd-yyyy') AND cust_id = ffsr.cust_id
AND acct_no = ffsr.acct_no AND filename = 'FEATURE.VB2B.201802090040'
GROUP BY cust_id||acct_no) mtnlist
FROM process.feature ffsr WHERE date_loaded BETWEEN TO_DATE('02-08-2018','MM-dd-yyyy')
AND TO_DATE('02-09-2018','MM-dd-yyyy') AND cust_id BETWEEN 0542185146 AND 0942025571
AND src_ind = 'B' AND filename = 'FEATURE.VB2B.201802090040'
AND letter_type = 'FA' ORDER BY cust_id;
With a little bit of help by XML, you might get it work. 在XML的帮助下,您可能会使其工作。 Example is based on HR schema. 示例基于HR模式。
SQL> select
2 listagg(s.department_name, ',') within group (order by null) result
3 from departments s, departments d;
from departments s, departments d
*
ERROR at line 3:
ORA-01489: result of string concatenation is too long
SQL>
SQL> select
2 rtrim(xmlagg(xmlelement (e, s.department_name || ',')).extract
3 ('//text()').getclobval(), ',') result
4 from departments s, departments d;
RESULT
--------------------------------------------------------------------------------
Administration,Administration,Administration,Administration,Administration,Admin
SQL>
This demo sourced from livesql.oracle.com 该演示源于livesql.oracle.com
-- Create table with 93 strings of different lengths, plus one NULL string. Notice the only ASCII character not used is '!', so I will use it as a delimiter in LISTAGG.
create table strings as
with letters as (
select level num,
chr(ascii('!')+level) let
from dual
connect by level <= 126 - ascii('!')
union all
select 1, null from dual
)
select rpad(let,num,let) str from letters;
-- Note the use of LENGTHB to get the length in bytes, not characters.
select str,
sum(lengthb(str)+1) over(order by str rows unbounded preceding) - 1 cumul_lengthb,
sum(lengthb(str)+1) over() - 1 total_lengthb,
count(*) over() num_values
from strings
where str is not null;
-- This statement implements the ON OVERFLOW TRUNCATE WITH COUNT option of LISTAGG in 12.2. If there is no overflow, the result is the same as a normal LISTAGG.
select listagg(str, '!') within group(order by str) ||
case when max(total_lengthb) > 4000 then
'! ... (' || (max(num_values) - count(*)) || ')'
end str_list
from (
select str,
sum(lengthb(str)+1) over(order by str) - 1 cumul_lengthb,
sum(lengthb(str)+1) over() - 1 total_lengthb,
count(*) over() num_values
from strings
where str is not null
)
where total_lengthb <= 4000
or cumul_lengthb <= 4000 - length('! ... (' || num_values || ')');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.