如何将clob数据转换为Oracle中的多个列?

如何将clob数据转换为Oracle中的多个列?

问题描述:

在Oracle表中,我有一个clob列(TEXT),其数据如下所示。如何将clob数据转换为Oracle中的多个列?

"Employee ID: 1 
Hire Date: 24-Oct-2013 
Name: XXXXX 
Department: IT 

Employee ID : 2 
Name : YYYYY 
Hire Date : 20-May-2014 
Department: ITIS 


Hire Date: 17-May-2017 
Department:SMO 
Name: ZZZZZ 
Employee ID: 3" 

以上CLOB数据需要被转换为多列像下面

Employee_ID Hire_Date  Name  Department 
---------------------------------------------------- 
1    24-Oct-2013  XXXXX  IT 
2    20-May-2014  YYYYY  ITIS 
3    17-May-2017  ZZZZZ  SMO 

请帮我在这。

+1

您可能没有权力改变这一点,但Oracle对XML有极好的支持,并且自从12c以来,对JSON的支持相当不错。假装自由文本是结构化数据只是坏的体系结构。我的意思是,这些属性甚至不是以相同的顺序。 – APC

+1

那么这里所谓的结构是什么?每个clob中的属性是否相同?每行有一个属性是否有保证?每个所谓的记录是否具有相同的编号和名称属性?或者你需要依靠空白行来确定“记录”?是的,这些成帧文本的一部分? – APC

+0

是的,每行将有一个属性,并且属性名称将保持不变。是的,在记录之间将会有多于一个新的行字符。文本。 – sar12089

下面的代码是从您的字符串中获取数据,然后插入列temporarytable,如果你不需要temperory table只要你想

首先创建temperoryEmployeeinfo这样

可以使用从字符串获取数据的逻辑
create global temporary table EmployeeInfo 
(
    EmployeeID   varchar2(15), 
    HireDate    varchar2(15), 
    Name     varchar2(100), 
    Department   varchar2(10) 
) 
on commit preserve rows; 

二使用这个代码(这是pl/sql test script

declare 

lv_string varchar2(4000) := 'Employee ID: 1 
Hire Date: 24-Oct-2013 
Name: XXXXX 
Department: IT 

Employee ID : 2 
Name : YYYYY 
Hire Date : 20-May-2014 
Department: ITIS 


Hire Date: 17-May-2017 
Department:SMO 
Name: ZZZZZ 
Employee ID: 3'; 

    lv_Token varchar2(4000); 
    lv_Part varchar2(4000); 
    lv_FirstPart varchar2(4000); 
    lv_SecondPart varchar2(4000); 
    li pls_integer := 0; 
    lv_EmployeeID varchar2(15); 
    lv_HireDate varchar2(15); 
    lv_Name varchar2(100); 
    lv_Department varchar2(10); 
    function v_Partition(av_source long, av_separator varchar2, 
          ai_nth pls_integer) return varchar2 is 
     li_Sep pls_integer := length(av_Separator); 
     li_Begin pls_integer := 1 - li_Sep; 
     li_End pls_integer; 
     lv_Output long; 
    begin 
     li_End := instr(av_source, av_separator, 1, ai_nth); 
     if ai_Nth > 1 then 
     li_Begin := instr(av_source, av_separator, 1, ai_nth - 1); 
     if li_Begin = 0 then 
      return null; 
     end if; 
     end if; 
     if li_End > 0 then 
     lv_Output := substr(av_Source, li_Begin + li_Sep, 
          li_End - li_Begin - li_Sep); 
     elsif length(av_Source) >= li_Begin + li_Sep then 
     lv_Output := substr(av_Source, li_Begin + li_Sep, 
          length(av_Source) - li_Begin); 
     end if; 
     return lv_Output; 
    end; 

    function v_Token(av_source in out nocopy varchar2, av_separator varchar2) 
     return varchar2 is 
     lv_token varchar2(4000); 
     li_pos pls_integer; 
    begin 
     li_pos := instr(av_source, av_separator, 1, 1); 
     if li_pos > 0 then 
     lv_token := rtrim(substr(av_source, 1, li_pos - 1)); 
     av_source := substr(av_source, li_pos + length(av_separator)); 
     else 
     lv_token := rtrim(av_source); 
     av_source := ''; 
     end if; 
     if av_Separator = ' ' then 
     av_Source := trim(av_Source); 
     end if; 
     return lv_token; 
    end; 
begin 
    while lv_string is not null loop 
     lv_Token := v_Token(lv_string, chr(10)); 
     if lv_Token is not null then 
     li := li + 1; 
     lv_FirstPart := trim(v_Partition(lv_Token, ':', 1)); 
     put(lv_FirstPart); 
     lv_SecondPart := trim(v_Partition(lv_Token, ':', 2)); 
     if lv_FirstPart like '%Employee ID%' then 
      lv_EmployeeID := lv_SecondPart; 
     elsif lv_FirstPart like '%Hire Date%' then 
      lv_HireDate := lv_SecondPart; 
     elsif lv_FirstPart like '%Name%' then 
      lv_Name := lv_SecondPart; 
     elsif lv_FirstPart like '%Department%' then 
      lv_Department := lv_SecondPart; 
     end if; 
     if li = 4 then 
      insert into EmployeeInfo 
      values 
       (lv_EmployeeID, lv_HireDate, lv_Name, lv_Department); 
      li := 0; 
     end if; 
     end if; 
    end loop; 


    --select * from EmployeeInfo; -- you can select from table 
end;