zoukankan      html  css  js  c++  java
  • 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 21150 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;

  • 相关阅读:
    Springmvc+Easyui 搜索,新增,删除,修改
    重炉后-文件上传下载
    文件下载
    easyui-dialog里面的东西
    Mysql多表查询
    spring框架-spring.xml配置文件
    面向对象15.3String类-常见功能-判断
    面向对象15.3String类-常见功能-转换
    面向对象15.3String类-常见功能-获取-2
    面向对象15.3String类-常见功能-获取-1
  • 原文地址:https://www.cnblogs.com/princessd8251/p/3883883.html
Copyright © 2011-2022 走看看