Hi, I had the same error retrieving CLOB data when I set client's NLS_LANG
to AMERICAN_AMERICA.UTF8.

Here is the part of the trace with the error:

OCILobGetLength(026F74D4,026F776C,026F68B4,0140FAC8)=SUCCESS
OCILobRead(026F74D4,026F776C,026F68B4,0140FACC,1,01CE0B04,485,00000000,00000
000,0,1)=NEED_DATA
       OCILobRead field 2 NEED_DATA: LOBlen 485, LongReadLen 4000, BufLen
485, Got 161
OCIErrorGet(026F776C,1,"<NULL>",0140F964,"��@a",1024,2)=NO_DATA
        0 (rc=0): undef
    !! ERROR: 99 ' (DBD NEED_DATA: OCILobRead)'
    <- fetchrow_arrayref= undef row1 at test_clob.pl line 11
    -> disconnect for DBD::Oracle::db (DBI::db=HASH(0x1ce3a88)~0x1ce39c8)

Looks like OCI function got the length of the LOB field correctly, but by
some reasons couldn't read all bytes (got stuck on 161 out of 485). 

I posted a message about it some time ago with the details. 
I'd be happy if somebody could help to find out what's going on with the
combination (CLOB+UTF8).

Irina.

-----Original Message-----
From: Joern Reder [mailto:joern@;dimedis.de] 
Sent: Friday, October 18, 2002 11:39 AM
To: [EMAIL PROTECTED]
Subject: Problems retrieving CLOB's from Oracle in UTF8



Hi,

sorry, the mail got long, but it took me some time to reproduce the 
problematic behaviour and I think we need this detail level to 
understand what's going wrong here...

We're using Perl 5.8.0, DBI 1.30 and DBD::Oracle 1.12, both client and 
server on Linux. We just extend our application framework to support 
UTF8 seamlessly. Nearly everything works well. Only retrieving CLOB's 
from an Oracle 8.1.7 database, which was created with the character set
"german_germany.utf8", fails.

With this small script I can reproduce the error:

--snip--
  #!/usr/bin/perl

  require 5.008;

  use strict;
  use warnings;

  use DBI;
  use DBD::Oracle qw(:ora_types);
  use Encode;

  $ENV{NLS_LANG} = "german_germany.utf8";

  main: {
      my $dbh = DBI->connect (
              "dbi:Oracle:DB",
              "USER", "PASS",
              {
                      AutoCommit  => 1,
                      RaiseError  => 1,
                      PrintError  => 0,
                      LongTruncOk => 1,
              }
      );

      eval { $dbh->do ("drop table clob_test") };

      $dbh->do (
              "create table clob_test (
                      id  integer,
                      str clob,
                      txt varchar2(255)
              )"
      );

      my $id = 0;

      my $data = "some data ���";

      # INSERT -----------------------------------------------------

      my $sth = $dbh->prepare ("insert into clob_test values (?, ?, ?)");

      utf8::upgrade($data);

      { use bytes; print "put: '$data'\n" }

      $sth->bind_param (1, ++$id );
      $sth->bind_param (2, $data, { ora_type => ORA_CLOB } );
      $sth->bind_param (3, $data );
      $sth->execute;
      $sth->finish;

      # READ -------------------------------------------------------

      $sth = $dbh->prepare (
              "select txt, str
               from   clob_test
               where  id = ?"
      );

      $sth->execute ( $id );

      my ($txt) = $sth->fetchrow;
      my $chunk = $sth->blob_read (1, 0, 32768);

      Encode::_utf8_on ($chunk);

      { use bytes; print "got: '$chunk' / '$txt'\n" }

      print "clob result: ".($chunk eq $data ? "OK" : "NOT OK"),"\n";
      print "char result: ".($txt   eq $data ? "OK" : "NOT OK"),"\n";

      END { $dbh->disconnect if $dbh }
  }

--snip--

The $sth->blob_read line throws the following exception:

  DBD::Oracle::st blob_read failed:  (DBD NEED_DATA: OCILobRead)

But when I omit the $ENV{NLS_LANG} line, $sth->blob_read() works and the
script doesn't abort. Astonishingly even the result check at the end 
reports, that the clob variable is valid utf8-encoded! That means, 
Oracle omitted iso-latin-1/utf8 conversion, which is usually done, if 
the client isn't itself utf8-aware.

But exactly that happens to the varchar2 variable, which is reported as
wrong by the script (sure, because it was utf8-converted twice). This is the
script's output (without setting NLS_LANG, in the other case I get 
the exception quoted above):

  put: 'some data äüö' / 'some data äüö'
  got: 'some data äüö' / 'some data �¤�¼�¶'
  clob result: OK
  char result: NOT OK

I learn the following from this:

  a) blob_read() always throws an exception with
     NLS_LANG=german_germany.utf8

  b) as expected: when not setting NLS_LANG, Oracle converts
     values for character columns as expected from/to utf8

  c) but: when not setting NLS_LANG, Oracle does *not*
     utf8 convert any CLOB values

I think we should classify a) and c) as bugs, and b) as absolutely 
correct ;)

Does anybody has any hint what's going on here? Can DBD::Oracle can do 
something for me? Is it a (probably known) problem with the Oracle 
client libaray?

Also I would greatly apprectiate if future versions of DBI would take 
care of variable's utf8 states themself (converting to utf8 if necessary and
setting the utf8-flag for retrieved values - both only with Perl 
5.8.x and if the database encoding is utf8, or if the developer set an 
appropriate attribute or something like that).

Regards,

Joern

-- 
Joern Reder -- Software Development,  dimedis GmbH, 50672 Koeln
               http://www.dimedis.de/
supporting:    http://www.zyn.de/ http://www.exit1.org/
CPAN:          http://www.perl.com/CPAN/modules/by-module/CIPP/JRED/

Reply via email to