本人使用ODAC连接Oracle数据库,现在表中遇到了long型数据,查阅了很多帖子,大部分帖子说的都是(注意需要使用setCharacterStream方法设置LONG类型的字段的值)。而且大部分写的是存储过程,看不明白呀。
如果是在delphi下直接读取或者修改,改用什么方法呢?
还有人提到说sql语句有限制,只能是4000个字符一下才可以执行。所以要用setCharacterStream。
请各位高手赐教~!

解决方案 »

  1.   

    CREATE TABLE T_LONGTEST
    (
      ID        INTEGER                             NOT NULL,
      FILENAME  VARCHAR2(100 BYTE),
      CONTENT   LONG
    )
    LOGGING 
    NOCACHE
    NOPARALLEL;CREATE UNIQUE INDEX PK_T_LONGTEST ON T_LONGTEST
    (ID)
    LOGGING
    NOPARALLEL;ALTER TABLE T_LONGTEST ADD (
      CONSTRAINT PK_T_LONGTEST PRIMARY KEY (ID));插入LONG类型的数据    BufferedReader bufReader = new BufferedReader(new FileReader(file));
        Integer id = Integer.valueOf(PubFun1.CreateMaxNo(TEST_LONG_ID, 1));
        PreparedStatement pstmt = con.prepareStatement(INSERT_LONG_SQL);
        pstmt.setObject(1, id);
        pstmt.setObject(2, fileName);
        pstmt.setCharacterStream(3, bufReader, (int) length);
        int retValue = pstmt.executeUpdate();
        if (retValue != 1) {
            logger.error("Error on insert value");
        }
        bufReader.close();
        pstmt.close();INSERT_LONG_SQL的值为:
    INSERT INTO T_LONGTEST(ID, FILENAME, CONTENT) VALUES (?, ?, ?)
    注意需要使用setCharacterStream方法设置LONG类型的字段的值.读取LONG类型的数据读取也需要使用Stream的方式来读取,下面的代码片断说明了读取LONG类型的字段的方法.
        PreparedStatement pstmt = con.prepareStatement(QUERY_LONG_COL_SQL);
        pstmt.setObject(1, id);
        ResultSet rs = pstmt.executeQuery();
        if (rs.next()) {
            Reader reader = rs.getCharacterStream(1);
            BufferedReader bufReader = new BufferedReader(reader);
            StringBuffer strBuf = new StringBuffer();
            String line;
            while ((line = bufReader.readLine()) != null) {
                strBuf.append(line);
                strBuf.append("\r\n");
            }
            bufReader.close();
            System.out.println("The content is:" + strBuf.toString());
        }
    QUEYR_LONG_COL_SQL的取值为:SELECT CONTENT FROM T_LONGTEST WHERE ID=?更新LONG类型的数据更新LONG类型的方法和插入的代码是一样的,只是SQL语句不同.下面的代码断说明了如何更新LONG类型的数据.(这个例子没有使用T_LONGTEST表)
        StringReader reader = new StringReader(xmlString);
        pstmt = con
                .prepareStatement(REPORT_MODEL_CONTENT_UPDATE_SQLSTRING);
        pstmt.setCharacterStream(1, reader, xmlString.length());
        pstmt.setInt(2, reportModelId);
        if (pstmt.executeUpdate() == 0) {
            logger
                    .error("Error on update");
        }
        reader.close();
    REPORT_MODEL_CONTENT_UPDATE_SQLSTRING的取值为:
    UPDATE REPORT_MODEL SET CONTENT=? WHERE REPORT_MODEL_ID=?从上面的例子可以看到,操作LONG类型的字段主要是通过CharacterStream,如果是更新数据库或者将数据插入到数据库中使用PreparedStatement的setCharacterStream,并且传入Reader类型的参数和字符串的长度.如果是检索数据库中的LONG类型的数据,那么使用getCharacterStream方法,获得一个Reader类型的对象,然后就可以从其中获取LONG类型的数据了.
      

  2.   


    odac没装,相信其sdk文档上有介绍的
    你的java代码转成delphi差不多了就。
     我用bde或ado处理大字段的步骤
    query.sql :='select  id,blob from some table';
    query.localte()
    query.editfieldbyname.asblob=somebufferquwery.post
    注意edit 和post之间仅处理这一个大字段
      

  3.   

    long类型,现在已经推荐使用blob类型了,字符使用clob类型
      

  4.   

    1.建立测试表
      create table ttt(id integer primary key,b blob,c clob);
    2.存入测试数据(我为了方便直接插入一条)
      insert into ttt values(1,'','');   //****注意,虽然这里可以正常执行,但我犯一个严重的错误为以后的操作埋下隐患*****//
      commit;
    3.打开delphi开在桌面上放置一上memo控件用来显示clob,与blob的内容(我这里只对blob进行说明)
    插入数据Insert:
    procedure TForm1.Button3Click(Sender: TObject);
    var
      vstream: TMemoryStream;
    begin
      vstream := TMemoryStream.Create;
      memo1.Lines.SaveToStream(vstream);
      adoquery1.SQL.Text := 'select * from TTT';
      adoquery1.Open;
      adoquery1.Append;   //   写BLOB字段之前使   处于编辑状态。
      adoquery1.FieldByName('ID').Value := 2;
      TBlobField(adoquery1.FieldByName('b')).LoadFromStream(vstream);
      adoquery1.Post;
    end;
    修改数据Edit:
    procedure TForm1.Button1Click(Sender: TObject);
    var
      vstream: TMemoryStream;
    begin
      orasession1.StartTransaction;
      vstream := TMemoryStream.Create;
      memo1.Lines.SaveToStream(vstream);
      with oraquery2 do
      begin
        close;
        sql.text := ' select * from TTT where id=1';
        open;
        oraquery2.Edit;
        TBlobField(FieldByName('b')).LoadFromStream(vstream);
        post;
      end;
      orasession1.Commit;
    end;对于clob与blob字段要利用DBMS包进行初始化,如这样:
    insert into ttt values(1,empty_clob(),empty_blob())
      

  5.   

    界面严重变形扭曲的一个csdn。谢谢上面的各位。我没有权利去修改数据库中的字段类型,没办法。能不能给一个方案来解决掉long字段,都2009年了,哈哈。还是得用long.
      

  6.   

    怎么从blob或者是clob数据类型里面往外读数据呀,插入和更新、删除都能实现,不会取数。我就郁闷。
      

  7.   

    blob的读取和插入、更新,已经解决了。原来对流的认识还是肤浅呀。没家指针读取的位置参数。明天还没有好的答案就结贴了,谢谢各位,恨透了long型,哈哈。