【问题标题】:String split for a CLOB value and insert splitted strings after a certain position as new row对 CLOB 值进行字符串拆分,并在某个位置后插入拆分后的字符串作为新行
【发布时间】:2016-03-11 02:31:09
【问题描述】:

我有一个字符串,其中有几个用';'分隔的句子。 我需要一个解决方案将字符串拆分为单独的行并将它们插入另一个表中。

分割字符串的条件如下:

字符串长度应最多容纳 699 个字符并以最近的 ';' 结尾字符,因为它标志着语句的结束,我们不希望它在中途结束。

例如:如果我们有一个像“abcdefg;thjiksfg;a;”这样的字符串 我们希望我们的字符串长度最多为 12 个字符 那么拆分和处理后的结果行应该具有像

这样的值
row1:abcdefg; 
row2:thjiksfg;a; 

请建议我如何使用 pl/sql 过程来做到这一点。

当前字符串作为 CLOB 值存储在表中,因为它可以容纳多达 7000/8000 个字符。

非常感谢您对此提供任何帮助。

【问题讨论】:

  • @Gordon 编辑了标签。谢谢

标签: sql database oracle plsql split


【解决方案1】:

请尝试以下步骤。在程序内部,我将 clob 数据放入 v_text。根据您的要求,您也可以将 clob 数据作为变量传递给程序。

   `PROCEDURE proc_split_str --(ur_clob_data IN CLOB)
     AS
    v_text_full CLOB;
    length_of_str PLS_INTEGER:=1;
    v_text CLOB;
    v_text_temp1 CLOB;
    v_text_temp CLOB;
    position PLS_INTEGER:=1;

    BEGIN
      /*getting data from table to v_text*/
        SELECT ur_colm_clob 
          INTO v_text
          FROM ur_table;

        WHILE(length_of_str>0)LOOP


         v_text_temp1:= SUBSTR(v_text_full,1,699);

         v_text_temp:= v_text_temp1;

             v_text_full:=SUBSTR(v_text_full,LENGTH(v_text_temp1)+1,LENGTH(v_text_full)-LENGTH(v_text_temp1));

          length_of_str:=  LENGTH(v_text_full);


        WHILE (position>0) LOOP

          /*splitting clob data and stored in v_text*/
            position   :=INSTR(v_text_temp,';',1);

             IF position >0 THEN
                v_text:=SUBSTR(v_text_temp,1,position-1);
                    v_text_temp:=SUBSTR(v_text_temp,length(v_text)+2,length(v_text_temp)-length(v_text)-1);
             ELSIF position=0 THEN
                v_text      :=v_text_temp;
                v_text_temp :=null;
             END IF;

             INSERT INTO ur_new_table(ur_column)
             VALUES (v_text);


        END LOOP;

   END LOOP;

END;
/`

【讨论】:

  • 感谢您的回答。我明白您的意思,但我的主要挑战是“我如何获得 ';' 的位置应该出现在 699 个字符之前”我没有看到你在任何地方都考虑过这个值。你能解释一下我如何考虑这个值,因为这是要求的主要棘手部分。
  • 已编辑代码,以便将整个字符串拆分为长度为 699 的字符的小字符串,然后在另一个循环中处理该字符串以使用 ';' 拆分。
  • @anju 谢谢你明白了你的意思并修改它以满足我的要求。
  • @Pritha 如果我的回答符合您的要求,请将其标记为有用。
【解决方案2】:

我可以使用以下示例代码使其在SQL SERVER 中工作,在此示例中使用最大允许长度为 15。 (不是一个很好的代码,只是为了演示这个想法!)

这个想法是
* 用分号分割字符串
* 继续连接拆分值,直到它们达到最大允许长度
* 插入目标表

Declare @sentences varchar(max) = 'hi;hey buddy;how are you;see you again;bye;';
SELECT splitdata 
INTO #TempTable 
FROM dbo.fnSplitString(@sentences,';') --function to spit string into rows

DECLARE @tempSentence VARCHAR(MAX) = ''
DECLARE @tempBackup VARCHAR(MAX) = ''
DECLARE @current VARCHAR(MAX) = ''
WHILE EXISTS (select splitdata from #TempTable)
BEGIN
    SET @tempBackup = @tempSentence;
    SET @current = (SELECT TOP 1 splitdata FROM #TempTable) + ';'
    SET @tempSentence = @tempSentence + @current;
    IF LEN(@tempSentence) > 15
    BEGIN
        --BMS_OUTPUT.PUT_LINE('Sentence = ' || @tempBackup);
        INSERT INTO dbo.MySentences VALUES(@tempBackup)
        SET @tempBackup = '';
        SET @tempSentence = @current;
    END
    DELETE TOP (1) FROM #TempTable
END
INSERT INTO dbo.MySentences VALUES(@tempSentence)
DROP TABLE #TempTable

结果:

我不知道Oracle,但你可以尝试类似(修正语法)

DECLARE @tempSentence VARCHAR(MAX)
DECLARE @tempBackup VARCHAR(MAX)
BEGIN --split code from > https://lalitkumarb.com/2014/12/02/split-comma-delimited-string-into-rows-in-oracle/
  FOR str IN (
        WITH DATA AS (
        SELECT 'sentence1;sentence2;sentence3;sentence4;' str FROM dual --table here
    )
    SELECT trim(regexp_substr(str, '[^;]+', 1, LEVEL)) str
    FROM DATA
    CONNECT BY instr(str, ',', 1, LEVEL - 1) > 0
  )
  LOOP
    @tempBackup = @tempSentence;
    @tempSentence = @tempSentence || str || ';';
    IF LENGTH(@tempSentence) > 699 THEN
        BMS_OUTPUT.PUT_LINE('Sentence = ' || @tempBackup);
        --insert @tempBackup to your table
        @tempBackup = '';
        @tempSentence = str || ';';
    END IF;
  END LOOP;
  BMS_OUTPUT.PUT_LINE('Last Sentence = ' || @tempSentence);
  --insert @tempSentence to your table
END;

【讨论】:

  • @arghya 感谢。将尝试在 oracle 中使用此逻辑,因为逻辑似乎很准确
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-01
  • 1970-01-01
相关资源
最近更新 更多