2017-03-24 28 views
4

我需要將此字段限制爲4000個字符。我如何限制在列表agg?謝謝。限制在oracle sql查詢中返回的字符

LISTAGG(ORDER_IMPRESSION.IMPRESSION, ',') WITHIN GROUP (ORDER BY ORDER_IMPRESSION.LINE) 
+0

數據倉庫內幕博客有一個相關條目這裏,https://blogs.oracle.com/datawarehousing /項/ managing_overflows_in_listagg。 –

回答

1

只有一點努力。事情是這樣的:

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 - 之後沒有任何內容。它並沒有削減印象。這種邏輯是可能的,但它確實使查詢復​​雜化。

0

你可以寫一個自定義的聚集函數聚集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 
) 
1

你可以計算運行總字符串長度的(使用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 
); 
1

如果你是一個12.2早期採用者,可以使用在溢出TRUNCATE子句...

ON OVERFLOW TRUNCATE

+0

現在這個技巧對全世界幾乎沒有人會有所幫助。但這對未來的尋求者會有幫助。 – APC