ORACLE中按长度分割字符串(保持单词完整性和数值完整性)

 由于客户需求中对报文的格式需求变化,增加了对发货人格式进行分割.要求如下:
NAD+CZ+++发货人1+发货人2:发货人3:发货人4:发货人5'
     发货人1(35):shipper;发货人的前35个字符(小于等于35个字符)
     发货人2~5(35):以35个字符(小于等于35个字符)为一段,对发货人进行分割;需要保持单词的完整性,
                    保持数值的完整性;
                    若发货人超长(大于35*5个字符),则在品名的后面添加 “*超长的发货人信息”
我们平常对字符串的分割都会给出分割的特殊符号,而它要求的则是要根据长度,和保持单词完整性和数值的完整性,
比如一字符串:”this is a test string ” 现在要求是每5个字符为一段,则分割出来的应该是:this : is a : test: string”也就是说任一单词不能被分割开.如果超过了,则取前面完整的单词,如果不足,则拼凑单词.
最关键的是把要分割的字符串分割出其完整的单词,(用数组来保存,ORACLE中可以定义数组变量).
自己写了个函数(oracle中的函数:D).代码贴在下面.

CREATE OR REPLACE FUNCTION FUC_PRATITION_STR
( PI_PARTITION_STR   IN   VARCHAR2
, PI_PARTITION_LEN   IN INT  --分割的长度
, PI_GET_PARTITION   IN   INT  --取分割第几段的字符
) RETURN VARCHAR2
AS
   BEGIN
   DECLARE TYPE WORD_PARTITION IS TABLE OF VARCHAR2(32767)
   INDEX BY BINARY_INTEGER;
    V_WORD_PARTITION  WORD_PARTITION;
    V_WORD_SECTION    WORD_PARTITION;
 V_INDEX     INT   := 0;
 V_START           INT   := 0;
 V_FILTER_STR      VARCHAR2(4000);
    V_COUNT           INT   := 0;
    V_NUM             INT   := 1;
    V_WORD            VARCHAR2(1000) := ' ';
    V_IND             INT   := 0;
    BEGIN

    --分割字符串,保证单词完整性和数据完整性。
    V_FILTER_STR      := LTRIM(RTRIM(PI_PARTITION_STR)); 
 IF( V_FILTER_STR IS NOT NULL) THEN
  WHILE(V_FILTER_STR IS NOT NULL) LOOP
   V_INDEX := INSTR(V_FILTER_STR,' ');
   IF(V_INDEX > 0) THEN    
    V_WORD_PARTITION(V_COUNT) := SUBSTR(V_FILTER_STR,V_START,V_INDEX);
    V_FILTER_STR    :=RTRIM(LTRIM(SUBSTR(V_FILTER_STR,V_INDEX+1,LENGTH(V_FILTER_STR)- V_INDEX+1)));
    
   ELSE
    V_WORD_PARTITION(V_COUNT) := V_FILTER_STR;
    V_FILTER_STR    := '';
      END IF;
            V_COUNT := V_COUNT + 1;
  END LOOP;
 END IF; 
   
    --拼凑字符串使之满足一定的长度
    IF V_WORD_PARTITION.COUNT = 1 THEN
       V_WORD_SECTION(0) := V_WORD_PARTITION(0);
    ELSE
        FOR V_NUM IN 0..V_WORD_PARTITION.COUNT-1 LOOP
         IF(V_NUM = V_WORD_PARTITION.COUNT -1) THEN
               V_WORD_SECTION(V_IND) := V_WORD_PARTITION(V_NUM);
         ELSE  IF((LENGTH(REPLACE(V_WORD_PARTITION(V_NUM),' '))+LENGTH(V_WORD_PARTITION(V_NUM+1))) > PI_PARTITION_LEN) THEN
                   V_WORD_SECTION(V_IND) := V_WORD_PARTITION(V_NUM);
                   V_IND := V_IND + 1;
               ELSE
                   V_WORD := V_WORD_PARTITION(V_NUM) ||' '||V_WORD_PARTITION(V_NUM+1);
                   V_WORD_PARTITION(V_NUM +1) := V_WORD;
               END IF;
         END IF;
        END LOOP;        
    END IF;
           
    -- GET THE SECTION WORD YOU WANT
    IF(PI_GET_PARTITION < V_WORD_SECTION.COUNT) THEN
       RETURN V_WORD_SECTION(PI_GET_PARTITION);
    ELSE RETURN '';
    END IF;
   END;
END FUC_PRATITION_STR;
/

posted @ 2007-11-22 18:05  糊涂小猪  阅读(2396)  评论(0编辑  收藏  举报