请教关于Java执行Oracle存储过程时参数为BLOB的有关问题

请问关于Java执行Oracle存储过程时参数为BLOB的问题!关于参数为BLOB的存储过程如下:--添加客户信息procedu

请问关于Java执行Oracle存储过程时参数为BLOB的问题!
关于参数为BLOB的存储过程如下:

    --添加客户信息
    procedure   addCustomer(--客户姓名
                                                v_customer_name   IN   CUSTOMER.NAME%TYPE,
                                                ...
                                                v_photo   IN   OUT   CUSTOMER.PHOTO%TYPE,
                                                --客户照片
                                                ...
                                                v_id   OUT   CUSTOMER.ID%TYPE
                                                --客户ID
                                                )
   
      IS
        v_char_id   customer.ID%TYPE;
        v_blob_photo   customer.photo%TYPE;
        ...  
  BEGIN
      --生成ID
      SELECT   SYS_GUID()   INTO   v_char_id   FROM   DUAL;      
 
    INSERT   INTO   CUSTOMER
            (ID,
              CUSTOMER_NAME,
              ...
              PHOTO,
              ...)
        VALUES
            (v_char_id,
              v_customer_name,
              ...
              EMPTY_BLOB(),     //先插入空BLOB
              ...
              );
   
        IF   (v_photo   IS   NOT   NULL)   THEN
            SELECT   PHOTO
                INTO   v_blob_photo
                FROM   CUSTOMER
              WHERE   CUSTOMER.ID   =   v_char_id
                  FOR   UPDATE;
       
            DBMS_LOB.OPEN(v_photo,   DBMS_LOB.lob_readonly);   --打开DBMS_LOB()包
            DBMS_LOB.OPEN(v_blob_photo,   DBMS_LOB.lob_readwrite);


            DBMS_LOB.append(v_blob_photo,   v_photo);   --追加要插入的照片到指定位置
            DBMS_LOB.close(v_photo);
            DBMS_LOB.close(v_blob_photo);
        END   IF;

        SELECT   v_char_id   INTO   v_id   FROM   DUAL;
   
        COMMIT;
=================================
以上省略部分与此问题无关的代码,存储过程已编译通过,如有问题请指正。

问题是Java部分,如何操作BLOB部分的代码?
Connection   conn   =   null;
OracleResultSet   ors   =   null;
OraclePreparedStatement   opst   =   null;

aCustomer.blobPhoto.putBytes(1,   photoBytes);   //   抛异常

oProc   =   (OracleCallableStatement)   conn.prepareCall( "{call   addCustomer(?,..?)} ");
oProc.setBLOB(1,   aCustomer.blobPhoto);

aCustomer.blobPhoto是BLOB类型,photoBytes是图片的字符流,想通过putBytes方法保存BLOB,作为参数传入存储过程,

抛出异常是:   空二进制大对象操作无效

上网查了一下,没有找到类似问题的解决方法。

请问有经验的朋友这种情况下存储过程和Java部分应该如何写?先谢谢了。


[解决办法]
帮你查的,看看
一般来说,大对象存储是把文件存到数据库中,当然也可以内存中的超大字符串。对于象图片这样的文件当然是用二进制存储,这里有很多误区,网络上的教程99%都是行不通的,连SUN自己的文档都一直错误,虽然错误很小。按说二进制文件应该存为BLOB类型,但JBDC2并不能直接对BLOB存入二进制文件,如果你这样做,会得到一个IO而不是SQL异常,为此花了我近两个小时才弄清楚。

  如果要把一个二制文件存入ORACLE,用标准的JDBC你就要用LONG ROW类型:

create table tb_file(name varchar(20),detail long row);

  然后

File file = new File( "aaa.gif ");
int fileLength =(int) file.length();
InputStream fin = new FileInputStream(file);
PreparedStatement pstmt = con.prepareStatement( "insert into tb_file values( 'aaa.gif ',?) ");
pstmt.setBinaryStream (1, fin, fileLength);
pstmt.executeUpdate();

  如果你一定要用BLOB存储,你就必须用ORACLE自己的方法:

create table tb_file(name varchar(20),detail BLOB);
con.setAutoCommit(false);
stmt.executeUpdate( "insert into tb_file values( 'aaa.gif ',empty_blob()) ");

  下面必须SELECT得到BLOB的对象再向里写:

rs = stmt.executeQuery( "select detail from tb_file where name= 'aaa.gif ' for upfdate " );
if(rs.next())
{
Blob blob = rs.getBlob(1);
BinaryOutputStream out = ((oracle.sql.BLOB)blob).getBinaryOutputStream();
byte[] b = new byte[((oracle.sql.BLOB)blob).getBufferSize];
InputStream fin = new FileInputStream(file);
int len = 0;
while( (len = fin.read(b)) != -1)
out.write(b,0,len);
fin.close();
out.close();
con.commit();
}

  同样读取数据你并不能象LONG ROW那样

InputStream in = rs.getBinaryInputStream( "detail ");

  而要

Blob blob = rs.getBlob( "detail ");
in = blob.getBinaryStream();

以上是转贴的一个关于大数据存储的方法