通过计算总行数进行修剪

时间:2018-01-22 09:07:09

标签: sql oracle plsql

我有一个VARCHAR2(210 CHAR)字段,必须在一个单词的末尾分成6行,最多35个字符。现在,对于下面的文字,我得到7行不应该发生。在这种情况下,我需要修剪到第7行的文本。请帮帮我。

示例:

WE REFER TO OUR PIN 103 QUOTED HERE
UNDER WHICH WAS SENT UNDER TRN 
QUOTED IN FIELD 20 AND PROCESSED 
UNDER YOUR REFERENCE IN FIELD 21 
BEST REGARDS PAYMENT INVESTIGATIONS
CENTRALIZED OPERATIONS CENTRE BOV 
MALTA.

要截断的第7行文字。

2 个答案:

答案 0 :(得分:1)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE table_name (
  value VARCHAR2(210)
);

INSERT INTO table_name ( value )
VALUES ( 'WE REFER TO OUR PIN 103 QUOTED HERE'
        || ' UNDER WHICH WAS SENT UNDER TRN'
        || ' QUOTED IN FIELD 20 AND PROCESSED'
        || ' UNDER YOUR REFERENCE IN FIELD 21'
        || ' BEST REGARDS PAYMENT INVESTIGATIONS'
        || ' CENTRALIZED OPERATIONS CENTRE BOV'
        || ' MALTA.' );

查询1

SELECT REGEXP_REPLACE(
         REGEXP_REPLACE(
           value,
           '(\S{0,35})\s*', -- Break any words longer than 35 characters
           '\1 '            -- and replace multiple white spaces with one space.
                            -- Will always leave a trailing space.
         ),
            '^(.{0,35})'    -- Up to 35 characters
         || '( (.{0,35}))?' -- Word break then up to 35 characters
         || '( (.{0,35}))?' -- Word break then up to 35 characters  
         || '( (.{0,35}))?' -- Word break then up to 35 characters
         || '( (.{0,35}))?' -- Word break then up to 35 characters
         || ' .*$',         -- Word break then rest of string to truncate (if any).
         '\1'
         || CHR(10) || '\3'
         || CHR(10) || '\5'
         || CHR(10) || '\7'
         || CHR(10) || '\9'
       ) As lines
FROM   table_name

<强> Results

|                               LINES |
|-------------------------------------|
| WE REFER TO OUR PIN 103 QUOTED HERE |
| UNDER WHICH WAS SENT UNDER TRN      |
| QUOTED IN FIELD 20 AND PROCESSED    |
| UNDER YOUR REFERENCE IN FIELD 21    |
| BEST REGARDS PAYMENT INVESTIGATIONS |

查询2

SELECT LISTAGG(
         TRIM( l.COLUMN_VALUE ),
         CHR(10)
       ) WITHIN GROUP ( ORDER BY ROWNUM ) AS lines
FROM   (
  SELECT ROWID As rid,
         REGEXP_REPLACE(
           value,
           '(\S{0,35})\s*', -- Break any words longer than 35 characters
           '\1 '            -- and replace multiple white spaces with one space.
         ) AS value
  FROM   table_name
) t
CROSS JOIN
TABLE(
  CAST(
    MULTISET(
      SELECT REGEXP_SUBSTR( t.value, '.{0,35} ', 1, LEVEL )
      FROM   DUAL
      CONNECT BY LEVEL <= REGEXP_COUNT( t.value, '.{0,35} ' )
             AND LEVEL <= 5 -- Number of lines
    ) AS SYS.ODCIVARCHAR2LIST
  )
) l
GROUP BY rid

<强> Results

|                               LINES |
|-------------------------------------|
| WE REFER TO OUR PIN 103 QUOTED HERE |
| UNDER WHICH WAS SENT UNDER TRN      |
| QUOTED IN FIELD 20 AND PROCESSED    |
| UNDER YOUR REFERENCE IN FIELD 21    |
| BEST REGARDS PAYMENT INVESTIGATIONS |

答案 1 :(得分:0)

通过循环完成:

DECLARE
    src            VARCHAR2 (1000)
        := 'WE REFER TO OUR PIN 103 QUOTED HERE UNDER WHICH WAS SENT UNDER TRN QUOTED IN FIELD 20 AND PROCESSED UNDER YOUR REFERENCE IN FIELD 21 BEST REGARDS PAYMENT INVESTIGATIONS CENTRALIZED OPERATIONS CENTRE BOV MALTA. MALTA. MALTA. MALTA. MALTA. MALTA. MALTA. MALTA. MALTA.';
    target         VARCHAR2 (210);
    rowBuffer      VARCHAR2 (210);
    rowCount       INT := 0;

    maxRowLength   INT := 35;
    maxRowCount    INT := 6;
BEGIN
    -- Split text into words and loop through words
    FOR i IN (    SELECT TRIM (REGEXP_SUBSTR (src,
                                              '[^ ]+',
                                              1,
                                              LEVEL))
                             l
                    FROM DUAL
              CONNECT BY LEVEL <= REGEXP_COUNT (src, ' ') + 1)
    LOOP
        -- Check if the current word can be added into rowbuffer
        IF (LENGTH (rowBuffer) + LENGTH (i.l) >= maxRowLength)
        THEN
            -- If row ist too long, add current row to target-string and start new buffer
            target := target || CHR (13) || CHR (10) || rowBuffer;
            rowBuffer := i.l;
            rowCount := rowCount + 1;
        ELSE
            -- enough room: add current word to rowBuffer
            rowBuffer := rowBuffer || ' ' || i.l;
        END IF;

        -- Let's have a look at our current row..
        DBMS_OUTPUT.put_line (rowBuffer);
        DBMS_OUTPUT.put_line ('***********************************');

        IF (rowCount >= maxRowCount)
        THEN
            -- We stop if we got enough rows
            DBMS_OUTPUT.put_line ('We hit maxRows!');
            EXIT;
        END IF;
    END LOOP;

    DBMS_OUTPUT.put_line ('************* RESULT  *************');
    DBMS_OUTPUT.put_line (target);
    DBMS_OUTPUT.put_line ('***********************************');
END;

我承认:MTO解决方案更酷;)。但是在此解决方案中,您可以配置rowlength和-count。