Insert BLOB && CLOB from PL/SQL and JDBC
For PL/SQL
1)Create Directory Where BLOB resides.
create or replace directory temp as '/oradata2';
-- if the directory name you created not qoted, then you can only use upper case to refer it.
-- create or replace directory temp as 'xxxx', the temp directory can only be refered as TEMP.
-- create or replace directory "temp" as 'xxxx', the temp directory can only be refered as temp.
2)Grant read permission to the user who work with this directory.
grant read on directory temp to test;
3)Create the Table which holds lob object.
-- the storage table for the image file
CREATE TABLE pdm (
dname VARCHAR2(30), -- directory name
sname VARCHAR2(30), -- subdirectory name
fname VARCHAR2(30), -- file name
iblob BLOB); -- image file
4)Create the procedure that insert BLOB objects.
-- create the procedure to load the file
CREATE OR REPLACE PROCEDURE load_file (
pdname VARCHAR2,
psname VARCHAR2,
pfname VARCHAR2)
IS
src_file BFILE;
dst_file BLOB;
lgh_file BINARY_INTEGER;
BEGIN
src_file := bfilename('TEMP', pfname);
-- insert a NULL record to lock
INSERT INTO pdm (dname, sname, fname, iblob) VALUES (pdname, psname, pfname, EMPTY_BLOB()) RETURNING iblob INTO dst_file;
-- lock record
SELECT iblob INTO dst_file FROM pdm
WHERE dname = pdname
AND sname = psname
AND fname = pfname
FOR UPDATE;
-- open the file
dbms_lob.fileopen(src_file, dbms_lob.file_readonly);
-- determine length
lgh_file := dbms_lob.getlength(src_file);
-- read the file
dbms_lob.loadfromfile(dst_file, src_file, lgh_file);
-- update the blob field, this step can be ignored as lob type is using pointer , privious step we have changed the content of the lob.
UPDATE pdm SET iblob = dst_file WHERE dname = pdname AND sname = psname AND fname = pfname;
-- close file
dbms_lob.fileclose(src_file);
END load_file;
/
5)Execute the Procedure.
SQL> exec load_file('TEMP','This is Image','tritha7.png');
PL/SQL procedure successfully completed.
6) From OS see the BLOB size.
SQL> !ls -l /oradata2/tritha7.png
-rwxr-xr-x 1 oracle oinstall Jun 9 01:55 /oradata2/tritha7.png
7)From Oracle Determine Blob size.
1 declare
2 a blob;
3 begin
4 select iblob into a from pdm;
5 dbms_output.put_line(dbms_lob.getlength(a));
6* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> set serverout on
SQL> /
21150
For JDBC:
java.sql.PreparedStatement pstmt = null;
ResultSet rs = null;
String query = ""; conn.setAutoCommit(false);
query = "insert into clobtest_table(id,picstr) values(?,empty_clob())";
java.sql.PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setString(1,"001");
pstmt.executeUpdate();
pstmt = null
query = "select picstr from clobtest_table where id = '001' for update";
pstmt = con.prepareStatement(query)
rs = pstmt.executeQuery(); oracle.sql.CLOB clobtt = null;
if(rs.next()){
clobtt = (oracle.sql.CLOB)rs.getClob(1);
}
Writer wr = clobtt.getCharacterOutputStream();
wr.write(strtmp);
wr.flush();
wr.close();
rs.close();
con.commit(); (2)通过sql/plus查询是否已经成功插入数据库
*************************************************
PL/SQL的包DBMS_LOB来处理LOB数据。察看刚才的插入是否成功。使用DBMS_LOB包的getlength这个procedure来检测是否已经将str存入到picstr字段中了。如: SQL> select dbms_lob.getlength(picstr) from clobtest_table; (3)对数据库clob型执行读取操作
************************************************* 读取相对插入就很简单了。基本步骤和一半的取数据库数据没有太大的差别。
String description = ""
query = "select picstr from clobtest_table where id = '001'";
pstmt = con.prepareStatement(query);
ResultSet result = pstmt.executeQuery();
if(result.next()){
oracle.jdbc.driver.OracleResultSet ors = (oracle.jdbc.driver.OracleResultSet)result;
oracle.sql.CLOB clobtmp = (oracle.sql.CLOB) ors.getClob(1);
if(clobtmp==null || clobtmp.length()==0){
System.out.println("======CLOB对象为空 ";
description = "";
}else{
description=clobtmp.getSubString((long)1,(int)clobtmp.length());
System.out.println("======字符串形式 "+description);
}
}
补充一个队LOB进行深度COPY的例子
create or replace
procedure NDSSP_backup_fund (fund_id_in in varchar2 ,selector_in in varchar2,
time_in in timestamp,blob_in in BLOB)
is
key number;
blob_tmp blob;
begin
delete from fund_backup bf where bf.selector = selector_in and bf.fund_id = fund_id_in;
select fund_backup_seq.nextval into key from dual;
insert into fund_backup values(key,selector_in,fund_id_in,empty_blob(),time_in);
select content into blob_tmp from fund_backup where id = key for update; -- we can ignore this as the insert statement already hold the X row lock.
dbms_lob.copy(blob_tmp, blob_in, dbms_lob.getLength(blob_in));
end NDSSP_backup_fund;
11G 的insert into xxx select 也支持LOB字段复制了. 下面是个例子
SQL> select * from test.blobtest;
ID CONTENTS
---------- ------------------------------------------------------------
1 504B0304140002000800D380F8446CFABED08E36030051E7220012000000
2 504B0304140002000800D380F8446CFABED08E36030051E7220012000000
SQL> conn test/test
已连接。
SQL> create table test2(id int primary key, aa blob);
表已创建。
SQL> insert into test2 select * from blobtest;
已创建2行。
SQL> select * from test2;
ID AA
---------- ------------------------------------------------------------
1 504B0304140002000800D380F8446CFABED08E36030051E7220012000000
2 504B0304140002000800D380F8446CFABED08E36030051E7220012000000
dbms_lob.LOADBLOBFROMFILE && dbms_lob.loadclobfromfile 的诡异用法
create or replace dir DUMP_DIR as 'd:\myzip'
grant read,write on directory DUMP_DIR to test;
create table blobtest (id int primary key,contents blob);
declare
l_blob blob;
l_bfile bfile;
DEST_OFFSET NUMBER;
SRC_OFFSET NUMBER;
begin
DEST_OFFSET:=1;
SRC_OFFSET:=1;
insert into test.BLOBTEST values (4, empty_blob()) returning contents into l_blob;
l_bfile := bfilename('DUMP_DIR', 'gpdb_ora_16750.zip');
dbms_lob.fileopen(l_bfile);
dbms_lob.LOADBLOBFROMFILE(l_blob,l_bfile, dbms_lob.getlength(l_bfile),DEST_OFFSET,SRC_OFFSET); -- 这里DEST_OFFSET 和 SRC_OFFSET 参数不能少,1表示从头开始.
dbms_lob.fileclose(l_bfile);
COMMIT;
end;
/
create table demo( id int primary key,bb clob);
declare
l_clob clob;
l_bfile bfile;
DEST_OFFSET NUMBER;
SRC_OFFSET NUMBER;
csid NUMBER;
lang_context NUMBER;
warning NUMBER;
begin
DEST_OFFSET:=1;
SRC_OFFSET:=1;
csid :=0;
lang_context :=0;
warning :=0;
insert into demo values (1, empty_clob()) returning bb into l_clob;
l_bfile := bfilename('DUMP_DIR', 'aa.txt');
dbms_lob.fileopen(l_bfile);
dbms_lob.loadclobfromfile(l_clob, l_bfile,DBMS_LOB.LOBMAXSIZE,DEST_OFFSET,SRC_OFFSET,csid,lang_context,warning);
dbms_lob.fileclose(l_bfile);
COMMIT;
end;
各个参数的解释如下:
| amount | DBMS_LOB.LOBMAXSIZE (IN) | Load the entire file |
| dest_offset | 1 (IN) | start from the beginning |
| src_offset | 1 (IN) | start from the beginning |
| csid | 0 (IN) | default csid, use destination csid |
| lang_context | 0 (IN) | default language context |
| warning | 0 (OUT) | no warning message, everything is ok |
补充
在对LOB字段插入数据的时候,如果是CLOB,可以直接写字符串(前提是小于4000,字符串直接量最大4000字符).
如果是BLOB,可以用utl_raw.cast_to_raw,下面是一个例子。
insert into GPCORRHISTATT(id,corrhist_id,contents) values(2,2,utl_raw.cast_to_raw('aaaaaaaaaaddcddd'));
BLOB/CLOB 互相转换
CREATE OR REPLACE FUNCTION clob_to_blob(b IN CLOB default empty_clob()) RETURN BLOB
AS
res BLOB;
b_len number := dbms_lob.getlength(b) ;
dest_offset1 NUMBER := 1;
src_offset1 NUMBER := 1;
amount_c INTEGER := DBMS_LOB.lobmaxsize;
blob_csid NUMBER := DBMS_LOB.default_csid;
lang_ctx INTEGER := DBMS_LOB.default_lang_ctx;
warning INTEGER;
BEGIN
if b_len > 0 then
DBMS_LOB.createtemporary (res, TRUE);
DBMS_LOB.OPEN (res, DBMS_LOB.lob_readwrite);
DBMS_LOB.convertToBlob (res,
b,
amount_c,
dest_offset1,
src_offset1,
blob_csid,
lang_ctx,
warning
);
else
select empty_blob() into res from dual ;
end if ;
RETURN res;
END clob_to_blob;
CREATE OR REPLACE FUNCTION blob_to_clob (blob_in IN BLOB) RETURN CLOB
AS
v_clob CLOB;
v_varchar VARCHAR2(32767);
v_start PLS_INTEGER := 1;
v_buffer PLS_INTEGER := 32767;
tmp_num number;
BEGIN
DBMS_LOB.CREATETEMPORARY(v_clob, TRUE);
tmp_num := CEIL(DBMS_LOB.GETLENGTH(blob_in) / v_buffer);
if tmp_num > 0 then
FOR i IN 1..tmp_num
LOOP
v_varchar := UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_in, v_buffer, v_start));
DBMS_LOB.WRITEAPPEND(v_clob, LENGTH(v_varchar), v_varchar);
v_start := v_start + v_buffer;
END LOOP;
end if;
RETURN v_clob;
END blob_to_clob;
Insert BLOB && CLOB from PL/SQL and JDBC的更多相关文章
- PL/SQL详细介绍,设置oracle相关
1. 实现参照完整性 指若两个表之间具有主从关系(即主外键关系),当删除主表数据时,必须确保相关的从表数据已经被删除. 当修改主表的主键列数据时,必须确保相关从表数据已经被修改.为了实现级 ...
- 开发PL/SQL子程序和包及使用PL/SQL编写触发器、在JDBC中应用Oracle
1. 子程序的各个部分: 声明部分.可执行部分.异常处理部分(可选) 2.子程序的分类: A. 过程 - 执行某些操作 a. 创建过程的语法: CREATE [OR REPLACE] PROC ...
- PL/SQL客户端中执行insert语句,插入中文乱码
问题描述:在PL/SQL客户端中执行insert语句,插入中文乱码 解决方案: 1.执行脚本 select userenv('language') from dual; 结果为AMERICAN_ ...
- PL/SQL 如何导出INSERT语句
需要把查询出来的数据导出成Insert的语句.忽然发现不会用了. 上网查,找到一些,但都不尽如人意. 于是就写了这篇文章.助人助己. 在PL/SQL Developer左边的树状导航栏里,找到[Tab ...
- PL/SQL可以连oracle,但是jdbc连不上 【转】
场景描述 此处是jdbc连接: try { Class.forName("oracle.jdbc.driver.OracleDriver"); String url = " ...
- PL/Sql快速执行 insert语句的.sql文件
当全是 insert语句的.sql文件太大时(insert 语句条数太大),直接打开执行sql文件,pl/sql会卡死. 这是可以用pl/sql的命令窗口来执行.sql文件,操作步骤如下: 1.新建命 ...
- Oracle学习笔记十 使用PL/SQL
PL/SQL 简介 PL/SQL 是过程语言(Procedural Language)与结构化查询语言(SQL)结合而成的编程语言,是对 SQL 的扩展,它支持多种数据类型,如大对象和集合类型,可使用 ...
- 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》
本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...
- Netsuite Formula > Oracle函数列表速查(PL/SQL单行函数和组函数详解).txt
PL/SQL单行函数和组函数详解 函数是一种有零个或多个参数并且有一个返回值的程序.在SQL中Oracle内建了一系列函数,这些函数都可被称为SQL或PL/SQL语句,函数主要分为两大类: 单行函数 ...
随机推荐
- Android由一个activity 间隔5秒自动跳转到另外一个activity
Android由一个activity 间隔5秒自动跳转到另外一个activity 2013年10月10日18:03:42 //一.写一个定时器 5秒后开启 final Intent lo ...
- 关于如何用php 获取当前脚本的url
关于用php 获取当前脚本的url很多朋友会说很简单,但是要获取很详细的就要经过多次判断哦. $PHP_TIME = time();$PHP_SELF = isset($_SERVER['PHP_SE ...
- 使用System.out.print/prilntln() 输出时存在的问题
刚学习Java时第一个接触的method就是System.out.println() 方法.但是最近在使用它输出一些变量时出现了我不理解的现象,首先上代码: /* * * using method S ...
- 《GK101任意波发生器》升级固件发布(版本:1.0.2.build126)
一.固件说明: 硬件版本:0,logic.3 固件版本:1.0.2.build126 编译日期:2014-08-23 ====================================== 二. ...
- MSF命令 收集
一.msfconsole ? 帮助菜单 back 从当前环境返回 banner 显示一个MSF banner cd 切换目录 color 颜色转换 connect 连接一个主机 e ...
- 如何用Apache POI操作Excel文件-----如何用Apache POI 画一个离散图
有的时候,我们需要Excel中的数据,通过一个图画,可视化的表现出来. 那么这个时候,应该如何做呢?现在就借花献佛,以Apache POI自己提供的一个例子为例,给大家演示一下POI的API 如何画图 ...
- Apache Spark技术实战之1 -- KafkaWordCount
欢迎转载,转载请注明出处,徽沪一郎. 概要 Spark应用开发实践性非常强,很多时候可能都会将时间花费在环境的搭建和运行上,如果有一个比较好的指导将会大大的缩短应用开发流程.Spark Streami ...
- 循环btn上面的视图
#import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...
- eclipse编译异常修正:the project cannot be built until its prerequisite...
close错误的project,重新open , 再 clean下 .
- FloodLight使用感受
一个使用java语言编写的基于Openflow协议的SDN控制器. 基本架构同webserver一样,有一个维护交换机连接信息的底层模块,当有交换机同控制器连接时,floodlight会将此连接保存到 ...