限制在oracle sql查询中返回的字符

时间:2017-03-24 12:22:17

标签: sql oracle

我需要将此字段限制为4000个字符。如何将其限制在列表中?谢谢。

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

4 个答案:

答案 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条款......

ON OVERFLOW TRUNCATE