On Tue, Sep 21, 2004 at 12:30:17PM -0700, Ravi Kongara wrote:
> Hi,
> 
> I'm using DBI 1.42, DBD::Oracle1.14 built on Oracle 8, Perl 5.6.1 on 
> Solaris 9.
> Purpose of the script is to compare values between source and target 
> databases.
> Source db is Oracle 7.3 and target db is Oracle 8.1.7.
> Again and again i'm getting into the problem of losing precision/scale 
> of NUMBER values.
> DBI script selects/displays 39 digits after the decimal point, 
> eventhough database has stored 40 digits, cutting off
> last digit while selecting from source. Strangely, it displays all 40 
> digits from target, which is a Oracle 8 database.
> 
> When i select from SQLPLUS session, values are shown correctly. Both 
> source and target show 40 digits and they match.
> Is there any clue what's happening..? why the last digit is lost when i 
> select using DBI from Oracle 7.

DBD::Oracle simply asks for the columns as strings and it's Oracle itself
that performs the number to string conversion. DBD::Oracle gives
Oracle a buffer of 133 characters for NUMBER fields, so there's
pleanty of room to store the number.

> If, i use TO_CHAR function i get 39 digits from both source and target.

That's a key point. Oracle itself is happy to truncate the number.

I'm not sure why SQLPLUS behaves differently. It probably asks
Oracle to fetch the NUMBR as a raw number and then uses OCI library
functions to format it. That different code path may be the cause
of the different behaviour.

Tim.

> Code snippet
> --------------------------
> <. . . . .  >
> use DBI;
> use Getopt::Long;
> 
> my $src_test_value = $src_dbh->selectrow_array("select    
> CONVERSION_RATE from $src_schema_name.$src_table_name where  
> FROM_CURRENCY_CODE = 'ZAR' and conversion_date = (select 
> max(conversion_date) from $src_schema_name.$src_table_name where 
> FROM_CURRENCY_CODE = 'ZAR')");
> print "src conv rate = $src_test_value\n";
> 
> my $tgt_test_value = $tgt_dbh->selectrow_array("select    
> CONVERSION_RATE from $ods_schema_name.$ods_table_name where  
> FROM_CURRENCY_CODE = 'ZAR' and conversion_date = (select 
> max(conversion_date) from $ods_schema_name.$ods_table_name where 
> FROM_CURRENCY_CODE = 'ZAR')");
> print "ods conv rate = $tgt_test_value\n";
> <. .  . . .  . >
> --------------------------
> values printed are...
> 
> Comparing src -> tgt
> src conv rate = .159616919393455706304868316041500399042
> ods conv rate = .1596169193934557063048683160415003990423
> ------------------------------------------------------
> 
> 
> Thanks,
> Ravi
> 

Reply via email to