Разделить CLOB на несколько столбцов VARCHAR2 по разделителю - PullRequest
0 голосов
/ 05 мая 2019

У меня есть таблица со столбцами:

  • f_name - Varchar
  • f_content - CLOB

table1

f_name     f_content
test1.txt  YL*1**50*1~
           RX*1~
           LR*2~
test2.txt  YL*1**49*1~
           EE*1~
           WW*2~

f_content содержит более 4000 символов, а иногда и более 10000 символов.

Можно ли создать 3 столбца Varchar2 и разделить до 4000 символов в каждом столбце до самого последнего ~, чтобы охватить весь CLOB?

Вывод будет:

f_name     f_content       f_content_varchar1    f_content_varchar2    f_content_varchar3
test1.txt  YL*1**50*1~     YL*1**50*1~           RX*1~                  LR*2~
           RX*1~
           LR*2~
test2.txt  YL*1**49*1~      YL*1**49*1~         EE*1~                   WW*2~
           EE*1~
           WW*2~

Пожалуйста, обратите внимание - я хочу разбить его на 3 столбца, НО ТОЛЬКО заканчивая до последнего ~, например, если строка заканчивается ~ на символе4003, то он не должен добавлять последнюю строку к столбцу varchar и всегда учитывать предыдущую строку, заканчивающуюся ~.

Примером может быть:

YL*1**50*1~
RX*1~
LR*2~

Скажем, 4000 символовзаканчивается на

"YL*1**50*1~
RX*1~
LR"

, затем в столбце varchar1 должно храниться:

"YL*1**50*1~
RX*1~"

, а в столбце varchar2 должно храниться:

"LR*2~"

Ответы [ 2 ]

0 голосов
/ 05 мая 2019

Если вас интересуют только первые 4000 символов, тогда преобразуйте значение в varchar2() и используйте регулярные выражения:

select t1.*,
       regexp_substr(f_content_str, '[^~]+[~]', 1, 1) as part1,
       regexp_substr(f_content_str, '[^~]+[~]', 1, 2) as part2,
       regexp_substr(f_content_str, '[^~]+[~]', 1, 3) as part3
from (select t1.*,
             dbms_lob.substr(t1.f_content, 4000, 1)  as f_content_str
      from t
     ) t;
0 голосов
/ 05 мая 2019

Если вы можете использовать CURSOR для манипулирования несколькими строками, этот следующий скрипт может помочь вам, предлагая идею. Обратите внимание, что я рассмотрел конечные точки 20, 40 и 60.

ВАЖНО: сначала проверьте этот скрипт в своей тестовой базе данных

ВАЖНО: Добавьте необходимое условие WHERE в инструкцию SELECT. В противном случае будут выбраны все записи

DECLARE @NAME NVARCHAR(MAX)
DECLARE @F_NAME NVARCHAR(MAX)

DECLARE @CUT_1 INT
DECLARE @CUT_2 INT


DECLARE db_cursor CURSOR FOR 
SELECT f_name,f_content 
FROM your_table 
--WHERE Plese add conditions to pick only columns you wants to adjust 

OPEN db_cursor  
FETCH NEXT FROM db_cursor INTO @F_NAME,@NAME  

WHILE @@FETCH_STATUS = 0  
BEGIN  

    DECLARE @A TABLE (POS INT)
    DECLARE @POS INT
    DECLARE @OLDPOS INT
    SELECT @OLDPOS=0        

    SELECT @POS=PATINDEX('%~%',@name) 
    WHILE @POS > 0 AND @OLDPOS <> @POS
     BEGIN
       INSERT INTO @A VALUES (@POS)
       SELECT @OLDPOS=@POS
       SELECT @POS=PATINDEX('%~%',SUBSTRING(@NAME,@POS + 1,LEN(@NAME))) + @POS
    END

    SELECT @CUT_1 = ISNULL(MAX([pos]),4000) from @a where pos <= 4000
    SELECT @CUT_2 = ISNULL(MAX([pos]),@CUT_1+4000) from @a where pos > @CUT_1 AND pos <= @CUT_1+4000


    UPDATE your_table
    SET [f_content_varchar1] = SUBSTRING(@Name,1,@CUT_1),
        [f_content_varchar2] = SUBSTRING(@Name,@CUT_1+1,@CUT_2-@CUT_1),
        [f_content_varchar3] = SUBSTRING(@Name,@CUT_2+1,12000-@CUT_2) 
    WHERE f_name = @F_NAME

    DELETE FROM @A
    SET @POS = NULL
    SET @OLDPOS = NULL
    SET @OLDPOS = NULL


    FETCH NEXT FROM db_cursor INTO  @F_NAME,@NAME 
END 

CLOSE db_cursor  
DEALLOCATE db_cursor 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...