【发布时间】:2015-03-05 09:16:01
【问题描述】:
我在 clob 字段中有平面文件,平面文件的结构如下所示。和平面文件包含 x 百万条记录。
col1,col2,col3,col4,col5,col6
A,B,C,,F,D
1,A,2,B,B,C
我不能用的传统方式
1-从 excel 中的 clob 或其他东西中获取数据,然后使用 sql-loader 将数据加载到表中。
2-目前我可以使用以下代码打印 clob 文件。
OPEN c_clob;
LOOP
FETCH c_clob INTO c;
EXIT
WHEN c_clob%notfound;
printout(c);
但上面代码中的问题是,如果我在插入语句中使用这个变量,那么由于 CLOB 到 VAR 插入,它会给出错误。
INSERT INTO Table1 VALUES(c);
commit;
ORA-22835: Buffer too small for CLOB to CHAR or BLOB to RAW conversion (actual: 848239, maximum: 4000)
是否有任何其他选项可用于处理来自 clob 字段的巨大平面文件并将其转储到表中。
目前我正在使用以下代码
declare
nStartIndex number := 1;
nEndIndex number := 1;
nLineIndex number := 0;
vLine varchar2(2000);
cursor c_clob is
select char_data from clob_table where seq=1022;
c clob;
procedure printout
(p_clob in out nocopy clob) is
offset number := 1;
amount number := 32767;
amount_last number := 0;
len number := dbms_lob.getlength(p_clob);
lc_buffer varchar2(32767);
line_seq pls_integer := 1;
-- For UNIX type file - replace CHR(13) to NULL
CR char := chr(13);
--CR char := NULL;
LF char := chr(10);
nCRLF number;
sCRLF varchar2(2);
b_finish boolean := true;
begin
sCRLF := CR || LF;
nCRLF := Length(sCRLF);
if ( dbms_lob.isopen(p_clob) != 1 ) then
dbms_lob.open(p_clob, 0);
end if;
amount := instr(p_clob, sCRLF, offset);
while ( offset < len )
loop
-- For without CR/LF on end file
If amount < 0 then
amount := len - offset + 1;
b_finish := false;
End If;
dbms_lob.read(p_clob, amount, offset, lc_buffer);
If b_finish then
lc_buffer := SUBSTR(lc_buffer,1,Length(lc_buffer)-1);
End If;
if (line_seq-1) > 0 then
amount_last := amount_last + amount;
offset := offset + amount;
else
amount_last := amount;
offset := amount + nCRLF;
end if;
amount := instr(p_clob, sCRLF, offset);
amount := amount - amount_last;
dbms_output.put_line('Line #'||line_seq||': '||lc_buffer);
line_seq := line_seq + 1;
end loop;
if ( dbms_lob.isopen(p_clob) = 1 ) then
dbms_lob.close(p_clob);
end if;
exception
when others then
dbms_output.put_line('Error : '||sqlerrm);
end printout;
begin
open c_clob;
loop
fetch c_clob into c;
exit when c_clob%notfound;
printout(c);
end loop;
close c_clob;
end;
这里的printout(c); 行(代码中的倒数第四行)逐行显示 clob 数据,直到缓冲区溢出。
预期结果:要从 clob 平面文件中读取数据并将行插入到表列中,这就是我想要实现的。 Constraints is Flat-Files 包含数百万条记录。
【问题讨论】:
-
不确定我是否理解...您有一个包含 CSV 数据的 CLOB,并且您想将其转换为另一个表中的单独列?或者只是将整个 CLOB 复制到另一个表?
Table1中的列是什么数据类型,c_clob光标后面的查询是什么? -
是的,Clob 包含 csv 文件。我想将其转换为另一个表中的单独列。
CURSOR c_clob IS SELECT char_data FROM table ; -
然后您需要逐行读取 CLOB(请参阅the
dbms_lobpackage),然后根据逗号分隔符将每一行拆分为标记。这两个部分都有很多例子,你只需要把它们放在一起。 -
或use a library,而不是自己创建。
-
@AlexPoole 您能否提供有关 DBMS_LOB 使用和将行拆分为令牌的任何参考。我找不到这样的工作示例。
标签: sql database plsql oracle11g