Ways of ensuring integers in the database are seen as numbers in perl?



Hi,

I'm working with DBD::Oracle at the moment and getting a little frustrated with integer numbers. I'd like my database returned integers to look like integers to Perl but they currently don't until I add 0 to them. Here is the problem:

The code calls an Oracle procedure which returns a reference cursor and fetching from this cursor leads to a mixture of utf8 encoded strings and integers. Mostly the data is fetched in one go with fetchall_arrayref but occasionally it is bound and fetched one row at a time. Either way the resulting array representing the database result-set is converted to JSON via JSON::XS. For a simple case where 1 row is returned containing 1 integer column I get the resulting JSON:

["1"] # this is a JSON string

However, if I add 0 to the fields I know are integers before I convert to JSON I get:

[1] # smaller and more accurate JSON number

The reason for this is that adding 0 to a Perl scalar seems to persuade Perl the scalar is an integer. The difference from Deve::Peek is as follows:

$num as returned from database:
SV = PV(0x9068f04) at 0x90288d4
REFCNT = 2
FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8)
PV = 0x90c1120 "1"\0 [UTF8 "1"]
CUR = 1
LEN = 4
$num after adding 0:
SV = PVMG(0x8f6f900) at 0x90288d4
REFCNT = 2
FLAGS = (PADBUSY,PADMY,SMG,IOK,pIOK)
IV = 1
NV = 0
PV = 0x90c1120 "1"\0
CUR = 1
LEN = 4
MAGIC = 0x90c0d78
MG_VIRTUAL = &PL_vtbl_utf8
MG_TYPE = PERL_MAGIC_utf8(w)
MG_LEN = -1

The thing is that JSON::XS (and a number of other modules we've using) uses SvIOKp (sv) (initially) to decide whether to try using this as a number and this seems perfectly reasonable to me. The problem is that now I have to go through all my result-sets from the database and add 0 to all the integers.

I was hoping binding the columns and declaring the bound type as ora_type => ORA_LONG would return me numbers but as the code I include below shows, this makes no difference.

Does anyone know of a way to get numbers (as I've described) back from DBD::Oracle.

And before anyone points it out, I know scalars in perl are strings or numbers depending on the context in which they are used but JSON::XS is not the only module looking at the underlying scalar flags.

use strict;
use warnings;
use DBI;
use DBD::Oracle qw(:ora_types SQLCS_IMPLICIT);
use Devel::Peek;
use JSON::XS;
use Data::Dumper;
use Encode;

my $h = DBI->connect('dbi:Oracle:XX', 'xxx', 'xxx') or die "connect!";
eval {local $h->{PrintError} = 0;$h->do(q/drop table martin_long/)};
$h->do(q/create table martin_long (a integer)/);
$h->do(q/insert into martin_long values(1)/);

my $s = $h->prepare(q/select * from martin_long/);
$s->execute;
my $num;
$s->bind_col(1, \$num, {ora_type => ORA_LONG});
my @data;
my @altdata;
while ($s->fetch) {
push @data, $num;
print "\$num as returned from database:\n";
Dump($num);
$num = $num + 0;
print "\$num after adding 0:\n";
Dump($num);
push @altdata, $num;
}
print Dumper(\@data);

print JSON::XS->new->encode(\@data), "\n";
print JSON::XS->new->encode(\@altdata), "\n";

Martin
--
Martin J. Evans
Easysoft Limited
http://www.easysoft.com
.



Relevant Pages

  • PostgreSQL and Customer Database
    ... I've been working on both SQL and Perl for a while now, ... get them all onto an SQL database, and be able to keep track of sales, as ... the database available to customers and potential customers, ...
    (perl.beginners)
  • Re: How to access MS Access from Perl?
    ... if you were to later migrate to MS SQL Server or Oracle ... minimize your load on the database server's compiled procedure cache. ... On the other hand, if startup time for your perl script is an issue, and ... slightly preferable to the bulkier DBI + DBD::ODBC. ...
    (comp.lang.perl)
  • Re: Attempted Simultaneous Access causes "Could not lock file"
    ... storing it in my MSAccess database. ... I just wrote another test perl program and pasted in the massive SELECT ... >> I can have multiple perl programs writing to the database, ... > It probably needs exclusive access to the entire Table if it's modifying ...
    (microsoft.public.access.tablesdbdesign)
  • Re: LAMP - Program Design with Perl
    ... > information and queries the MySQL database. ... > Maybe there are Perl modules to faciliate this kind of task? ... so I think it worthwhile to second Anno's suggestion on this method (eg. ... Aside from the hint about dispatch tables, ...
    (comp.lang.perl.misc)
  • Re: join two binary numbers
    ... use warnings; ... Perl is doing an bitwise or of each *byte* of the two strings, padding $num of the right with two zero bytes to match the length of $res. ...
    (comp.lang.perl.misc)