dbms_lob问题请教!!!

zdhack 2010-09-25 07:13:11
create or replace procedure getTable_XMLQUERY(table_name varchar2)
is
data clob;--用于保存数据
xmlfile utl_file.file_type;--文件类型变量
length pls_integer;
buffer varchar2(32767);
start_idx pls_integer default 1;
end_idx pls_integer default 32767;
begin
--将查询的数据转换为XML格式,并保存到clob中
data := dbms_xmlquery.getxml('select * from '||table_name);
--获取clob类型的变量data的长度
length := dbms_lob.getlength(data);
--得到文件实例,如果没有当前指明的文件系统会自动创建w表示写(write)
xmlfile := utl_file.fopen('EMP_DIR',table_name||'.xml','w');
--循环截取
loop
dbms_output.put_line(length);
--截取一段字符串放到BUFFER变量中
dbms_lob.read(data,end_idx,start_idx,buffer);
dbms_output.put_line(start_idx||'___..___'||end_idx);
--把BUFFER中的数据输出
utl_file.put(xmlfile,buffer);
exit when end_idx=length;
--重设循环变量
if end_idx+32767<length then
end_idx := end_idx+32767;
start_idx := start_idx+32767;
else
start_idx := start_idx+(length-end_idx);
end_idx := end_idx+(length-end_idx);
end if;
dbms_output.put_line(start_idx||'______'||end_idx);
--清空BUFFER
buffer := null;
end loop;
utl_file.fclose(xmlfile);
end;

上面代码循环第二次时就产生错误为什么呢!
此行代码有问题:
dbms_lob.read(data,end_idx,start_idx,buffer);
我发现end_idx它会被系统改变

希望各位高手解决
...全文
338 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
zdhack 2010-10-09
  • 打赏
  • 举报
回复
对,是的,那么应该怎么做呢
yuxian81 2010-10-08
  • 打赏
  • 举报
回复
第二个参数是in out 参数,当数据读取完毕后会修改该参数为实际读取的数据的长度.当该长度与你原先设置的长度值不一致时,表示读到末尾了。
zdhack 2010-10-02
  • 打赏
  • 举报
回复
怎么没有人回复我呢
zdhack 2010-10-01
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 wildwave 的回复:]
dbms_lob.read(data,end_idx,start_idx,buffer);里的参数并不是这样给的
DBMS_LOB.READ (
lob_loc IN CLOB CHARACTER SET ANY_CS,
amount IN OUT NOCOPY INTEGER,
offset IN INTEGER,
buffer OUT VARCHAR2 CHARACTER SET l……
[/Quote]

敢问您关于这个问题该怎么解决呢!您的回答非常专业,可是本人愚钝希望您详细讲一讲,如果给解决方案更好!
minitoy 2010-09-30
  • 打赏
  • 举报
回复
学习.
小灰狼W 2010-09-30
  • 打赏
  • 举报
回复
另外要注意一点
READ Procedure Parameters
Parameter Description
lob_loc Locator for the LOB to be read. For more information, see
Operational Notes.
file_loc The file locator for the LOB to be examined.
amount Number of bytes (for BLOBs) or characters (for CLOBs) to read,
or number that were read.
offset Offset in bytes (for BLOBs) or characters (for CLOBs) from the
start of the LOB (origin: 1).
buffer Output buffer for the read operation.

当lob对象为clob时,amount参数的单位是字符而不是字节。但你定义的buffer的长度32767却是字节。因此如果当你的clob中存在汉字(或者在某些字符集下每个字符占>1字节),此时还会有长度错误
小灰狼W 2010-09-30
  • 打赏
  • 举报
回复
dbms_lob.read(data,end_idx,start_idx,buffer);里的参数并不是这样给的
DBMS_LOB.READ (
lob_loc IN CLOB CHARACTER SET ANY_CS,
amount IN OUT NOCOPY INTEGER,
offset IN INTEGER,
buffer OUT VARCHAR2 CHARACTER SET lob_loc%CHARSET);
这两个参数是截取的长度和开始起始位置。第二次循环的时候,amount超过了32767
minitoy 2010-09-30
  • 打赏
  • 举报
回复
莫非拼成xml后都能超过5g?
minitoy 2010-09-30
  • 打赏
  • 举报
回复
看报错是你的查询结果太大了.存储不了,你查询结果多少数据量?
minitoy 2010-09-30
  • 打赏
  • 举报
回复
没问题啊
SQL> exec getTable_XMLQUERY('emp');

3171
1___..___3171

PL/SQL procedure successfully completed

SQL>

<?xml version = '1.0'?>
<ROWSET>
<ROW num="1">
<EMPNO>7369</EMPNO>
<ENAME>SMITH</ENAME>
<JOB>CLERK</JOB>
<MGR>1000</MGR>
<HIREDATE>12/17/1980 3:1:0</HIREDATE>
<SAL>800.1</SAL>
<DEPTNO>20</DEPTNO>
</ROW>
<ROW num="2">
<EMPNO>7499</EMPNO>
<ENAME>ALLEN</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>2/20/1981 4:2:0</HIREDATE>
<SAL>1600</SAL>
<COMM>300</COMM>
<DEPTNO>30</DEPTNO>
</ROW>
<ROW num="3">
<EMPNO>7521</EMPNO>
<ENAME>WARD</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>2/22/1981 1:1:1</HIREDATE>
<SAL>1250</SAL>
<COMM>500</COMM>
<DEPTNO>30</DEPTNO>
</ROW>
<ROW num="4">
<EMPNO>7566</EMPNO>
<ENAME>JONES</ENAME>
<JOB>MANAGER</JOB>
<MGR>7839</MGR>
<HIREDATE>4/2/1981 10:1:59</HIREDATE>
<SAL>2975</SAL>
<DEPTNO>20</DEPTNO>
</ROW>
<ROW num="5">
<EMPNO>7654</EMPNO>
<ENAME>MARTIN</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>9/28/1981 5:1:59</HIREDATE>
<SAL>1250</SAL>
<COMM>1400</COMM>
<DEPTNO>30</DEPTNO>
</ROW>
<ROW num="6">
<EMPNO>7698</EMPNO>
<ENAME>BLAKE</ENAME>
<JOB>MANAGER</JOB>
<MGR>7839</MGR>
<HIREDATE>5/1/1981 2:1:0</HIREDATE>
<SAL>2850</SAL>
<DEPTNO>30</DEPTNO>
</ROW>
<ROW num="7">
<EMPNO>7782</EMPNO>
<ENAME>CLARK</ENAME>
<JOB>MANAGER</JOB>
<MGR>7839</MGR>
<HIREDATE>6/9/1981 10:1:0</HIREDATE>
<SAL>2450</SAL>
<DEPTNO>10</DEPTNO>
</ROW>
<ROW num="8">
<EMPNO>7788</EMPNO>
<ENAME>SCOTT</ENAME>
<JOB>ANALYST</JOB>
<MGR>7566</MGR>
<HIREDATE>4/19/1987 1:1:1</HIREDATE>
<SAL>3000</SAL>
<DEPTNO>20</DEPTNO>
</ROW>
<ROW num="9">
<EMPNO>7839</EMPNO>
<ENAME>KING</ENAME>
<JOB>PRESIDENT</JOB>
<HIREDATE>11/17/1981 8:0:0</HIREDATE>
<SAL>5000</SAL>
<DEPTNO>10</DEPTNO>
</ROW>
<ROW num="10">
<EMPNO>7844</EMPNO>
<ENAME>TURNER</ENAME>
<JOB>SALESMAN</JOB>
<MGR>7698</MGR>
<HIREDATE>9/8/1981 0:3:0</HIREDATE>
<SAL>1500</SAL>
<COMM>0</COMM>
<DEPTNO>30</DEPTNO>
</ROW>
<ROW num="11">
<EMPNO>7876</EMPNO>
<ENAME>ADAMS</ENAME>
<JOB>CLERK</JOB>
<MGR>7788</MGR>
<HIREDATE>5/23/1987 9:1:1</HIREDATE>
<SAL>1100</SAL>
<DEPTNO>20</DEPTNO>
</ROW>
<ROW num="12">
<EMPNO>7900</EMPNO>
<ENAME>JAMES</ENAME>
<JOB>CLERK</JOB>
<MGR>7698</MGR>
<HIREDATE>12/3/1981 1:59:59</HIREDATE>
<SAL>950</SAL>
<DEPTNO>30</DEPTNO>
</ROW>
<ROW num="13">
<EMPNO>7902</EMPNO>
<ENAME>FORD</ENAME>
<JOB>ANALYST</JOB>
<MGR>7566</MGR>
<HIREDATE>12/3/1981 6:1:0</HIREDATE>
<SAL>3000</SAL>
<DEPTNO>20</DEPTNO>
</ROW>
<ROW num="14">
<EMPNO>7934</EMPNO>
<ENAME>MILLER</ENAME>
<JOB>CLERK</JOB>
<MGR>7782</MGR>
<HIREDATE>1/23/1982 9:1:1</HIREDATE>
<SAL>1300</SAL>
<DEPTNO>10</DEPTNO>
</ROW>
</ROWSET>
zdhack 2010-09-30
  • 打赏
  • 举报
回复
ERROR 位于第 1 行:
ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小
ORA-06512: 在"SYS.DBMS_LOB", line 715
ORA-06512: 在"SYSTEM.GETTABLE_XMLQUERY", line 20
ORA-06512: 在line 1

end_idx并不会按照我的if条件增长呀!而且系统会修改我的end_idx,只是为什么呢!
minitoy 2010-09-26
  • 打赏
  • 举报
回复
create or replace procedure getTable_XMLQUERY(table_name varchar2)
is
data clob;--用于保存数据
xmlfile utl_file.file_type;--文件类型变量
length pls_integer;
buffer varchar2(32767);
start_idx pls_integer default 1;
end_idx pls_integer default 32767;
begin
--将查询的数据转换为XML格式,并保存到clob中
data := dbms_xmlquery.getxml('select * from '||table_name);
--获取clob类型的变量data的长度
length := dbms_lob.getlength(data);
--得到文件实例,如果没有当前指明的文件系统会自动创建w表示写(write)
xmlfile := utl_file.fopen('EMP_DIR',table_name||'.xml','w');
--循环截取
if start_idx=1 and length <=32767 then
end_idx=length;
end if;
loop
dbms_output.put_line(length);
--截取一段字符串放到BUFFER变量中
dbms_lob.read(data,end_idx,start_idx,buffer);
dbms_output.put_line(start_idx||'___..___'||end_idx);
--把BUFFER中的数据输出
utl_file.put(xmlfile,buffer);
exit when end_idx=length;
--重设循环变量
if end_idx+32767<length then
end_idx := end_idx+32767;
start_idx := start_idx+32767;
else
start_idx := start_idx+(length-end_idx);
end_idx := end_idx+(length-end_idx);
end if;
dbms_output.put_line(start_idx||'______'||end_idx);
--清空BUFFER
buffer := null;
end loop;
utl_file.fclose(xmlfile);
end;
还是这样吧,效率高点.
minitoy 2010-09-26
  • 打赏
  • 举报
回复
因为你的文件长度小于32767...
create or replace procedure getTable_XMLQUERY(table_name varchar2)
is
data clob;--用于保存数据
xmlfile utl_file.file_type;--文件类型变量
length pls_integer;
buffer varchar2(32767);
start_idx pls_integer default 1;
end_idx pls_integer default 32767;
begin
--将查询的数据转换为XML格式,并保存到clob中
data := dbms_xmlquery.getxml('select * from '||table_name);
--获取clob类型的变量data的长度
length := dbms_lob.getlength(data);
--得到文件实例,如果没有当前指明的文件系统会自动创建w表示写(write)
xmlfile := utl_file.fopen('EMP_DIR',table_name||'.xml','w');
--循环截取
loop
dbms_output.put_line(length);
--截取一段字符串放到BUFFER变量中
if start_idx=1 and length<=32767 then
end_idx=length;
end if;
dbms_lob.read(data,end_idx,start_idx,buffer);
dbms_output.put_line(start_idx||'___..___'||end_idx);
--把BUFFER中的数据输出
utl_file.put(xmlfile,buffer);
exit when end_idx=length;
--重设循环变量
if end_idx+32767<length then
end_idx := end_idx+32767;
start_idx := start_idx+32767;
else
start_idx := start_idx+(length-end_idx);
end_idx := end_idx+(length-end_idx);
end if;
dbms_output.put_line(start_idx||'______'||end_idx);
--清空BUFFER
buffer := null;
end loop;
utl_file.fclose(xmlfile);
end;

3,490

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 高级技术相关讨论专区
社区管理员
  • 高级技术社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧