oracle中讀寫(xiě)blob字段的問(wèn)題解析
LOB類(lèi)型分為BLOB和CLOB兩種:BLOB即二進(jìn)制大型對(duì)像(Binary Large Object),適用于存貯非文本的字節(jié)流數(shù)據(jù)(如程序、圖像、影音等)。而CLOB,即字符型大型對(duì)像(Character Large Object),則與字符集相關(guān),適于存貯文本型的數(shù)據(jù)(如歷史檔案、大部頭著作等)。
下面以程序?qū)嵗f(shuō)明通過(guò)JDBC操縱Oracle數(shù)據(jù)庫(kù)LOB類(lèi)型字段的幾種情況。
先建立如下兩個(gè)測(cè)試用的數(shù)據(jù)庫(kù)表,Power Designer PD模型如下:
建表SQL語(yǔ)句為:
CREATE TABLE TEST_CLOB ( ID NUMBER(3), CLOBCOL CLOB)
CREATE TABLE TEST_BLOB ( ID NUMBER(3), BLOBCOL BLOB)
一、 CLOB對(duì)象的存取
1、往數(shù)據(jù)庫(kù)中插入一個(gè)新的CLOB對(duì)像
public static void clobInsert(String infile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 插入一個(gè)空的CLOB對(duì)像 */
stmt.executeUpdate("INSERT INTO TEST_CLOB VALUES ('111', EMPTY_CLOB())");
/* 查詢(xún)此CLOB對(duì)象并鎖定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
while (rs.next()) {
/* 取出此CLOB對(duì)像 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 向CLOB對(duì)像中寫(xiě)入數(shù)據(jù) */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出錯(cuò)回滾 */
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
2、修改CLOB對(duì)像(是在原CLOB對(duì)像基礎(chǔ)上進(jìn)行覆蓋式的修改)
public static void clobModify(String infile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查詢(xún)CLOB對(duì)象并鎖定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
while (rs.next()) {
/* 獲取此CLOB對(duì)像 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 進(jìn)行覆蓋式修改 */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出錯(cuò)回滾 */
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
3、替換CLOB對(duì)像(將原CLOB對(duì)像清除,換成一個(gè)全新的CLOB對(duì)像)
public static void clobReplace(String infile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 清空原CLOB對(duì)像 */
stmt.executeUpdate("UPDATE TEST_CLOB SET CLOBCOL=EMPTY_CLOB() WHERE ID='111'");
/* 查詢(xún)CLOB對(duì)象并鎖定 */
ResultSet rs = stmt.executeQuery("SELECT CLOBCOL FROM TEST_CLOB WHERE ID='111' FOR UPDATE");
while (rs.next()) {
/* 獲取此CLOB對(duì)像 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 更新數(shù)據(jù) */
BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
BufferedReader in = new BufferedReader(new FileReader(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出錯(cuò)回滾 */
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
4、CLOB對(duì)像讀取
public static void clobRead(String outfile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查詢(xún)CLOB對(duì)像 */
ResultSet rs = stmt.executeQuery("SELECT * FROM TEST_CLOB WHERE ID='111'");
while (rs.next()) {
/* 獲取CLOB對(duì)像 */
oracle.sql.CLOB clob = (oracle.sql.CLOB)rs.getClob("CLOBCOL");
/* 以字符形式輸出 */
BufferedReader in = new BufferedReader(clob.getCharacterStream());
BufferedWriter out = new BufferedWriter(new FileWriter(outfile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
out.close();
in.close();
}
} catch (Exception ex) {
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
二、 BLOB對(duì)象的存取
1、 向數(shù)據(jù)庫(kù)中插入一個(gè)新的BLOB對(duì)像
public static void blobInsert(String infile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 插入一個(gè)空的BLOB對(duì)像 */
stmt.executeUpdate("INSERT INTO TEST_BLOB VALUES ('222', EMPTY_BLOB())");
/* 查詢(xún)此BLOB對(duì)象并鎖定 */
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
while (rs.next()) {
/* 取出此BLOB對(duì)像 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 向BLOB對(duì)像中寫(xiě)入數(shù)據(jù) */
BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出錯(cuò)回滾 */
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
2、修改BLOB對(duì)像(是在原BLOB對(duì)像基礎(chǔ)上進(jìn)行覆蓋式的修改)
public static void blobModify(String infile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查詢(xún)BLOB對(duì)象并鎖定 */
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
while (rs.next()) {
/* 取出此BLOB對(duì)像 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 向BLOB對(duì)像中寫(xiě)入數(shù)據(jù) */
BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出錯(cuò)回滾 */
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
3、替換BLOB對(duì)像(將原BLOB對(duì)像清除,換成一個(gè)全新的BLOB對(duì)像)
public static void blobReplace(String infile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 清空原BLOB對(duì)像 */
stmt.executeUpdate("UPDATE TEST_BLOB SET BLOBCOL=EMPTY_BLOB() WHERE ID='222'");
/* 查詢(xún)此BLOB對(duì)象并鎖定 */
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222' FOR UPDATE");
while (rs.next()) {
/* 取出此BLOB對(duì)像 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 向BLOB對(duì)像中寫(xiě)入數(shù)據(jù) */
BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
BufferedInputStream in = new BufferedInputStream(new FileInputStream(infile));
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出錯(cuò)回滾 */
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
4、BLOB對(duì)像讀取
public static void blobRead(String outfile) throws Exception
{
/* 設(shè)定不自動(dòng)提交 */
boolean defaultCommit = conn.getAutoCommit();
conn.setAutoCommit(false);
try {
/* 查詢(xún)BLOB對(duì)像 */
ResultSet rs = stmt.executeQuery("SELECT BLOBCOL FROM TEST_BLOB WHERE ID='222'");
while (rs.next()) {
/* 取出此BLOB對(duì)像 */
oracle.sql.BLOB blob = (oracle.sql.BLOB)rs.getBlob("BLOBCOL");
/* 以二進(jìn)制形式輸出 */
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outfile));
BufferedInputStream in = new BufferedInputStream(blob.getBinaryStream());
int c;
while ((c=in.read())!=-1) {
out.write(c);
}
in.close();
out.close();
}
/* 正式提交 */
conn.commit();
} catch (Exception ex) {
/* 出錯(cuò)回滾 */
conn.rollback();
throw ex;
}
/* 恢復(fù)原提交狀態(tài) */
conn.setAutoCommit(defaultCommit);
}
觀(guān)察上述程序?qū)OB類(lèi)型字段的存取,我們可以看出,較之其它類(lèi)型字段,有下面幾個(gè)顯著不同的特點(diǎn):
一是必須取消自動(dòng)提交。
相關(guān)文章
oracle實(shí)現(xiàn)動(dòng)態(tài)查詢(xún)前一天早八點(diǎn)到當(dāng)天早八點(diǎn)的數(shù)據(jù)功能示例
這篇文章主要介紹了oracle實(shí)現(xiàn)動(dòng)態(tài)查詢(xún)前一天早八點(diǎn)到當(dāng)天早八點(diǎn)的數(shù)據(jù)功能,涉及Oracle針對(duì)日期時(shí)間的運(yùn)算與查詢(xún)相關(guān)操作技巧,需要的朋友可以參考下2019-10-10Oracle中查詢(xún)本月星期5的所有日期列表的語(yǔ)句
Oracle中查詢(xún)本月星期5的所有日期列表的語(yǔ)句,需要的朋友可以參考下2012-07-07Oracle逗號(hào)分隔列轉(zhuǎn)行實(shí)現(xiàn)方法
在做系統(tǒng)時(shí),經(jīng)常會(huì)遇到在一個(gè)字段中,用逗號(hào)或其他符號(hào)分隔存儲(chǔ)多個(gè)信息,例如保存某個(gè)用戶(hù)的一對(duì)多權(quán)限時(shí),在權(quán)限組這個(gè)字段中,就會(huì)逗號(hào)分隔保存多個(gè)權(quán)限編號(hào)。2010-12-12AWR 深入分析( Automatic Workload Repository )
本篇文章,小編為大家介紹一下關(guān)于AWR 深入分析( Automatic Workload Repository )有需要的朋友可以參考一下2013-04-04windows下oracle 11g r2 安裝過(guò)程與卸載詳細(xì)圖解
這篇文章主要介紹了windows下oracle 11g r2 安裝過(guò)程與卸載詳細(xì)圖解,需要的朋友可以參考下2016-04-04對(duì)學(xué)Oracle數(shù)據(jù)庫(kù)初學(xué)者的開(kāi)場(chǎng)篇
這篇文章主要介紹了對(duì)學(xué)Oracle數(shù)據(jù)庫(kù)初學(xué)者的開(kāi)場(chǎng)篇,方便想學(xué)習(xí)oracle數(shù)據(jù)庫(kù)的朋友2015-05-05詳解Oracle如何將txt文件中的數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù)
這篇文章主要介紹了Oracle如何將txt文件中的數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù),文中通過(guò)代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03