create or replace procedure FileToClob(p_Directory IN VARCHAR2,p_FileName IN VARCHAR2,p_AccNum IN varchar2) is v_FileLocator BFILE; v_CLOBLocator CLOB; begin SELECT sequence --出错行,直接跳到exception! INTO v_CLOBLocator FROM jiao.seq_info where accession_id = p_AccNum FOR UPDATE; -- Initialize the BFILE locator for reading. v_FileLocator := BFILENAME(p_Directory, p_FileName); DBMS_LOB.FILEOPEN(v_FileLocator, DBMS_LOB.FILE_READONLY); DBMS_LOB.LOADFROMFILE(v_CLOBLocator, v_FileLocator,DBMS_LOB.GETLENGTH(v_FileLocator));
DBMS_LOB.FILECLOSE(v_FileLocator); commit; EXCEPTION WHEN OTHERS THEN DBMS_LOB.FILECLOSE(v_FileLocator);
RAISE; rollback; end FileToClob; ??
还是不行,他压根就不执行到commit,直接在出错行跳出去了,应该是select那句有问题吧?
这样吧 begin begin SELECT sequence --出错行,直接跳到exception! INTO v_CLOBLocator FROM jiao.seq_info where accession_id = p_AccNum FOR UPDATE; exception when others then dbms_output.put_line('出错'); end; .....这样就知道是否与语句有关
意料之中,把select后面的执行语句隐去还是同样会出错
哪就在select语句发生错误了 一篇短文: 在Oracle 8i的SQL*Plus中如何利用LOB字段存取操作系统二进制文件 Oracle 8i数据库系统功能比前面版本更加完善,尤其是出现了BLOB,CLOB,NCLOB, BFILE这些LOB(大型对象)类型来取代功能有限的LONG、LONGRAW类型。BLOB字段最 大长度为4G(4,294,967,295)字节,而且不再象LONGRAW那样每个表中只是限制有一 个字段是LONGRAW(最长2G)型的。BLOB,CLOB,NCLOB为内部BLOB(数据通常在数据 库中存放),BFILE为外部LOB(所存储的只是指向外部操作系统文件的指针),用户可 以使用PL/SQL的包DBMS_LOB来处理LOB数据,但是遗憾的是,DBMS_LOB包只能将二进 制操作系统文件写入到BLOB字段中,却无法将BLOB字段中的二进制操作系统文件取回 到操作系统中,估计将来会有所改善。本文将就如何在SQL*Plus将WORD文件存入取出 ORACLE中作详细解释说明,供各位同行参考。在internal这个用户下给scott用户授权如下: SQL>grant create any directory to scott; SQL>grant create any library to scott; 在scott这个用户下执行下述语句:SQL>create table bfile_tab (bfile_column BFILE); SQL>create table utl_lob_test (blob_column BLOB); SQL>create or replace directory utllobdir as 'C:\DDS\EXTPROC'; SQL>set serveroutput on然后执行下面语句就将C:\DDS\EXTPROC目录下的word文件COM.doc存入到utl_lob_test 表中的blob_column字段中了。declare a_blob BLOB; a_bfile BFILE := BFILENAME('UTLLOBDIR','COM.doc'); --用来指向外部操作系统文件 begin insert into bfile_tab values (a_bfile) returning bfile_column into a_bfile; insert into utl_lob_test values (empty_blob()) returning blob_column into a_blob; dbms_lob.fileopen(a_bfile); dbms_lob.loadfromfile(a_blob, a_bfile, dbms_lob.getlength(a_bfile)); dbms_lob.fileclose(a_bfile); commit; end; / SQL>show errors 此时可以使用DBMS_LOB包的getlength这个procedure来检测是否已经将该word文件存入 到blob字段中了。如: SQL> select dbms_lob.getlength(blob_column) from UTL_LOB_TEST; 结果如下: DBMS_LOB.GETLENGTH(BLOB_COLUMN) ------------------------------- 83968 说明该word文件已经存入到blob字段中去了。
谢谢你一直关注,不过我对上面的代码有几个疑问: 1.不需要另外给bfile单独建个表吧,直接使用这个类型不就行了吗? 2.returning *** into ***这个句式什么意思? 3.如果我要在某行插入clob的值,比如说在accession_id ='N08005',不是还是要用到select这句话吗? 4.如果我在开头加上UPDATE jiao.seq_info SET sequence = EMPTY_CLOB();这个方法还是有错的!
SELECT nvl(sequence,EMPTY_CLOB()) INTO v_CLOBLocator FROM jiao.seq_info where accession_id = p_AccNum FOR UPDATE;
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96612/d_lob.htm
那commit应该放在什么位置?
v_FileLocator BFILE;
v_CLOBLocator CLOB;
begin
SELECT sequence --出错行,直接跳到exception!
INTO v_CLOBLocator
FROM jiao.seq_info
where accession_id = p_AccNum
FOR UPDATE;
-- Initialize the BFILE locator for reading.
v_FileLocator := BFILENAME(p_Directory, p_FileName);
DBMS_LOB.FILEOPEN(v_FileLocator, DBMS_LOB.FILE_READONLY); DBMS_LOB.LOADFROMFILE(v_CLOBLocator, v_FileLocator,DBMS_LOB.GETLENGTH(v_FileLocator));
DBMS_LOB.FILECLOSE(v_FileLocator);
commit;
EXCEPTION
WHEN OTHERS THEN
DBMS_LOB.FILECLOSE(v_FileLocator);
RAISE;
rollback;
end FileToClob;
??
begin
begin
SELECT sequence --出错行,直接跳到exception!
INTO v_CLOBLocator
FROM jiao.seq_info
where accession_id = p_AccNum
FOR UPDATE;
exception
when others then
dbms_output.put_line('出错');
end;
.....这样就知道是否与语句有关
一篇短文:
在Oracle 8i的SQL*Plus中如何利用LOB字段存取操作系统二进制文件
Oracle 8i数据库系统功能比前面版本更加完善,尤其是出现了BLOB,CLOB,NCLOB,
BFILE这些LOB(大型对象)类型来取代功能有限的LONG、LONGRAW类型。BLOB字段最
大长度为4G(4,294,967,295)字节,而且不再象LONGRAW那样每个表中只是限制有一
个字段是LONGRAW(最长2G)型的。BLOB,CLOB,NCLOB为内部BLOB(数据通常在数据
库中存放),BFILE为外部LOB(所存储的只是指向外部操作系统文件的指针),用户可
以使用PL/SQL的包DBMS_LOB来处理LOB数据,但是遗憾的是,DBMS_LOB包只能将二进
制操作系统文件写入到BLOB字段中,却无法将BLOB字段中的二进制操作系统文件取回
到操作系统中,估计将来会有所改善。本文将就如何在SQL*Plus将WORD文件存入取出
ORACLE中作详细解释说明,供各位同行参考。在internal这个用户下给scott用户授权如下:
SQL>grant create any directory to scott;
SQL>grant create any library to scott;
在scott这个用户下执行下述语句:SQL>create table bfile_tab (bfile_column BFILE);
SQL>create table utl_lob_test (blob_column BLOB);
SQL>create or replace directory utllobdir as 'C:\DDS\EXTPROC';
SQL>set serveroutput on然后执行下面语句就将C:\DDS\EXTPROC目录下的word文件COM.doc存入到utl_lob_test
表中的blob_column字段中了。declare
a_blob BLOB;
a_bfile BFILE := BFILENAME('UTLLOBDIR','COM.doc'); --用来指向外部操作系统文件
begin
insert into bfile_tab values (a_bfile)
returning bfile_column into a_bfile;
insert into utl_lob_test values (empty_blob())
returning blob_column into a_blob;
dbms_lob.fileopen(a_bfile);
dbms_lob.loadfromfile(a_blob, a_bfile, dbms_lob.getlength(a_bfile));
dbms_lob.fileclose(a_bfile);
commit;
end;
/
SQL>show errors
此时可以使用DBMS_LOB包的getlength这个procedure来检测是否已经将该word文件存入
到blob字段中了。如:
SQL> select dbms_lob.getlength(blob_column) from UTL_LOB_TEST;
结果如下:
DBMS_LOB.GETLENGTH(BLOB_COLUMN)
-------------------------------
83968
说明该word文件已经存入到blob字段中去了。
1.不需要另外给bfile单独建个表吧,直接使用这个类型不就行了吗?
2.returning *** into ***这个句式什么意思?
3.如果我要在某行插入clob的值,比如说在accession_id ='N08005',不是还是要用到select这句话吗?
4.如果我在开头加上UPDATE jiao.seq_info SET sequence = EMPTY_CLOB();这个方法还是有错的!
INTO v_CLOBLocator
FROM jiao.seq_info
where accession_id = p_AccNum
FOR UPDATE;