Re: DBD::ODBC fetch is returning string for integer

"Martin J. Evans" <[email protected]>
Newsgroups gmane.comp.lang.perl.modules.dbi.general
Message-ID <[email protected]>
On 19/05/2012 13:33, [email protected] wrote:
>> DBD::ODBC is returning strings for integers.  This results in incorrect values
>> for  bit wise operators.  (for ex:- $e='16'; $f = '32'  print $e&  $f returns
>> 12 instead of zero ). Is there a setting that can help us return integers as
>> 'integers'.
> It's safer (and easier) to make your perl code independent of the returned
> data type:
>
>   $e='16';
>   $f='32';
>   print $e&$f; # prints '12'
>   $e += 0; $f += 0;
>   print $e&$f; # prints '0'
>
>
> --      Peter Vanroose.
>
It is but that can be a really annoying thing to do it you have lots of 
columns you want as integers. The first case where I came across this 
where it was a substantial annoyance was using JSON::XS to convert data 
I'd retrieved from the database to JSON. The columns which are numbers 
are converted to "NNN" in the JSON output but I really wanted NNN (for 
reduced size and because some other languages parsing the JSON 
differentiate between "NNN" and NNN. Adding 0 to all of them was a PITA 
(think selectall_arrayref and then having to iterate over the entire 
result-set adding 0 to each integer field). It turns out JSON::XS 
attempts to spot numbers by looking to see if the pv in the scalar is set.

As a result and with Tim's help we added the DiscardString attribute to 
SQLBindCol and when combined with a TYPE (SQL_INTEGER, SQL_DECIMAL, 
SQL_NUMERIC) and a driver which supports it (DBD::ODBC and DBD::Oracle 
definitely) it will use sql_type_cast_svpv to cast the value to the 
right type and the pv is lost.

I added this support to DBD::ODBC but because rebinding a column in Perl 
on an existing statement does not actually end up calling SQLBindCol 
again it masked a problem in my test code which made it look like 
DiscardString was working when in fact it was not.

Strictly speaking DiscardString and sql_type_cast_svpv is not needed in 
DBD::ODBC when you specify the type as SQL_INTEGER as it should simply 
sv_setiv (which it did not) but it is still required for 
SQL_DECIMAL/SQL_NUMERIC.

I am working on a fix right now.

Martin
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.