我需要将此字段限制为4000个字符。如何将其限制在列表中?谢谢。
LISTAGG(ORDER_IMPRESSION.IMPRESSION, ',') WITHIN GROUP (ORDER BY ORDER_IMPRESSION.LINE)
答案 0 :(得分:2)
只需付出一点努力。像这样:
select listagg((case when running_len < 4000 then oi.impression end), ',') within group (order by oi.line)
from (select oi.*,
sum(length(oi.impression) + 1) over (partition by ?? order by oi.line) as running_len
from order_impression oi
) oi
group by ??;
计算运行长度,仅汇总不超过长度的值。 ??
是您用于聚合的任何内容。这确实假设line
是唯一的,因此order by
是稳定的。
这不包括超出长度的impression
- 之后没有任何内容。它并没有减少印象。这种逻辑是可能的,但它确实使查询复杂化。
答案 1 :(得分:2)
您可以计算字符串长度的运行总计(使用SUM(...) OVER (...)
分析函数),然后使用此字符串将字符串截断为4000个字符:
SELECT LISTAGG(
CASE
WHEN prev_len >= 4000 THEN NULL
WHEN prev_len + len <= 4000 THEN value
ELSE SUBSTR( value, 1, 4000 - prev_len )
END
) WITHIN GROUP ( ORDER BY line ) AS value
FROM (
SELECT impression,
line,
LENGTH( impression ) AS len,
COALESCE(
SUM( 1 + LENGTH( impression ) )
OVER ( ORDER BY line ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ),
0
) AS prev_len
FROM order_impression
);
答案 2 :(得分:0)
您可以编写自定义聚合函数,将VARCHAR2
聚合为CLOB
:
CREATE OR REPLACE TYPE CLOBAggregation AS OBJECT(
value CLOB,
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT CLOBAggregation
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT CLOBAggregation,
value IN VARCHAR2
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT CLOBAggregation,
returnValue OUT CLOB,
flags IN NUMBER
) RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT CLOBAggregation,
ctx IN OUT CLOBAggregation
) RETURN NUMBER
);
/
CREATE OR REPLACE TYPE BODY CLOBAggregation
IS
STATIC FUNCTION ODCIAggregateInitialize(
ctx IN OUT CLOBAggregation
) RETURN NUMBER
IS
BEGIN
ctx := CLOBAggregation( NULL );
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateIterate(
self IN OUT CLOBAggregation,
value IN VARCHAR2
) RETURN NUMBER
IS
BEGIN
IF value IS NULL THEN
NULL;
ELSIF self.value IS NULL THEN
self.value := value;
ELSE
self.value := self.value || ',' || value;
END IF;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateTerminate(
self IN OUT CLOBAggregation,
returnValue OUT CLOB,
flags IN NUMBER
) RETURN NUMBER
IS
BEGIN
returnValue := self.value;
RETURN ODCIConst.SUCCESS;
END;
MEMBER FUNCTION ODCIAggregateMerge(
self IN OUT CLOBAggregation,
ctx IN OUT CLOBAggregation
) RETURN NUMBER
IS
BEGIN
IF self.value IS NULL THEN
self.value := ctx.value;
ELSIF ctx.value IS NULL THEN
NULL;
ELSE
self.value := self.value || ',' || ctx.value;
END IF;
RETURN ODCIConst.SUCCESS;
END;
END;
/
CREATE FUNCTION CLOBAgg( value VARCHAR2 )
RETURN CLOB
PARALLEL_ENABLE AGGREGATE USING CLOBAggregation;
/
然后你可以这样做:
SELECT DBMS_LOB.SUBSTR( CLOBAGG( IMPRESSION ), 4000 )
FROM (
SELECT IMPRESSION
FROM ORDER_IMPRESSION
ORDER BY line
)
答案 3 :(得分:0)
如果你是12.2早期采用者,你可以使用ON OVERFLOW TRUNCATE条款......