如何将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
请帮我在这。
答
下面的代码是从您的字符串中获取数据,然后插入列temporary
table
,如果你不需要temperory table
只要你想
首先创建temperory
表Employeeinfo
这样
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;
您可能没有权力改变这一点,但Oracle对XML有极好的支持,并且自从12c以来,对JSON的支持相当不错。假装自由文本是结构化数据只是坏的体系结构。我的意思是,这些属性甚至不是以相同的顺序。 – APC
那么这里所谓的结构是什么?每个clob中的属性是否相同?每行有一个属性是否有保证?每个所谓的记录是否具有相同的编号和名称属性?或者你需要依靠空白行来确定“记录”?是的,这些成帧文本的一部分? – APC
是的,每行将有一个属性,并且属性名称将保持不变。是的,在记录之间将会有多于一个新的行字符。文本。 – sar12089