我需要將此字段限制爲4000個字符。我如何限制在列表agg?謝謝。限制在oracle sql查詢中返回的字符
LISTAGG(ORDER_IMPRESSION.IMPRESSION, ',') WITHIN GROUP (ORDER BY ORDER_IMPRESSION.LINE)
我需要將此字段限制爲4000個字符。我如何限制在列表agg?謝謝。限制在oracle sql查詢中返回的字符
LISTAGG(ORDER_IMPRESSION.IMPRESSION, ',') WITHIN GROUP (ORDER BY ORDER_IMPRESSION.LINE)
只有一點努力。事情是這樣的:
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
- 之後沒有任何內容。它並沒有削減印象。這種邏輯是可能的,但它確實使查詢復雜化。
你可以寫一個自定義的聚集函數聚集VARCHAR2
s轉換爲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
)
你可以計算運行總字符串長度的(使用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
);
數據倉庫內幕博客有一個相關條目這裏,https://blogs.oracle.com/datawarehousing /項/ managing_overflows_in_listagg。 –