Oracle, как установить для табуляции или конца строки, используя regexp_instr - PullRequest
0 голосов
/ 28 июня 2019

У меня есть следующий код

declare
l_clob       clob;
l_line       varchar2(32767);
l_field      varchar2(32767);
l_line_start  pls_integer := 1;
l_line_end    pls_integer := 1;
l_field_start pls_integer := 1;
l_field_end   pls_integer := 1;
begin
   select response_clob
   into   l_clob
   from   xxhr.xxhr_web_service_response
   where  response_id = 290;
   -- Loop through lines.
   loop
      l_line_end := dbms_lob.instr(l_clob, chr(10), l_line_start, 1);
      l_line := dbms_lob.substr(l_clob, l_line_end - l_line_start + 1, l_line_start);
      -- If this is a line with fields and not web service garbage.
      if substr(l_line, 1, 1) = '"' then
         l_field_start := 2;
         -- Loop through fields.      
         loop
            l_field_end := instr(l_line, chr(9), l_field_start, 1);
            l_field := substr(l_line, l_field_start, l_field_end - l_field_start);  
            dbms_output.put(l_field || ',');
            l_field_start := l_field_end + 1;
            exit when l_field_end = 0;
         end loop;
         dbms_output.put_line('');         
      end if;   
      l_line_start := l_line_end + 1;
      exit when l_line_end = 0;
   end loop;
end;   

, с которым я пытаюсь проанализировать эти clob данные теста:

LINE_TEXT
"PERSON_ID_NUMBER   30000   1223445454"
"PERSON_DOB 30000   01-01-1900"

Данные clob равны tabотделен и имеет chr(10) в конце.Я не знаком с regexp_instr, но в настоящее время я использую только instr для поиска разделителей tab;поэтому в нем отсутствует поле конца строки, и получается:

PERSON_ID_NUMBER,30000,,
PERSON_DOB,30000,,

Как я могу изменить instr на regexp_instr, чтобы также искать символ конца строки в дополнение к tab изатем правильно выбрать последнее поле?

Мне нужна функция для выполнения, так как она разбирает большие файлы.

Ответы [ 2 ]

0 голосов
/ 28 июня 2019

Исправлено с помощью:

declare
l_clob       clob;
l_line       varchar2(32767);
l_field      varchar2(32767);
l_line_start  pls_integer := 1;
l_line_end    pls_integer := 1;
l_field_start pls_integer := 1;
l_field_end   pls_integer := 1;
begin
   select response_clob
   into   l_clob
   from   xxhr.xxhr_web_service_response
   where  response_id = 290;
   -- Loop through lines.
   loop
      l_line_end := dbms_lob.instr(l_clob, chr(10), l_line_start, 1);
      l_line := dbms_lob.substr(l_clob, l_line_end - l_line_start + 1, l_line_start);
      -- If this is a line with fields and not web service garbage.
      if substr(l_line, 1, 1) = '"' then
         l_field_start := 2;
         -- Loop through fields.      
         loop
            l_field_end := instr(l_line, chr(9), l_field_start, 1);
            l_field := substr(l_line, l_field_start, l_field_end - l_field_start);  
            dbms_output.put(l_field || ',');
            exit when l_field_end = 0;
            l_field_start := l_field_end + 1;            
         end loop;
         l_field := substr(l_line, l_field_start);
         dbms_output.put_line(l_field);                           
      end if;   
      l_line_start := l_line_end + 1;
      exit when l_line_end = 0;
   end loop;
end;   
0 голосов
/ 28 июня 2019

Вы можете разделить строку столбца CLOB, конвертировав в char, а затем применить regexp_substr() как

with t as
(  
select level as row_num, regexp_substr(to_char(t.line_text),'^.*$',1,level,'m') as str
  from tab t
 connect by level <= length (to_char(t.line_text)) 
                   - length (replace (to_char(t.line_text), chr (10))) + 1
)
select row_num, regexp_replace(str,'[[:space:]]+',',') as str
  from t;   

 ROW_NUM STR
 ------- -----------------------------------------
 1       PERSON_ID_NUMBER,30000,1223445454
 2       PERSON_DOB,30000,01-01-1900

Демо

Редактировать: даже работает без конвертации to_char(), если ваш CLOB огромен, вам нужно шаг за шагом разделить на substr(str,1,4000), substr(str,4001,8000) ...

with t as
(
  select level as row_num, regexp_substr(substr(t.line_text,1,4000),'^.*$',1,level,'m') str
    from tab t
   connect by level <= length (substr(t.line_text,1,4000)) 
                     - length (replace(substr(t.line_text,1,4000), chr (10))) + 1 
)
select row_num, regexp_replace(substr(str,1,4000),'[[:space:]]+',',') as str
  from t   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...