ADO Select Problem
am 03.02.2007 00:29:35 von dmurrayGreetings,
For years, I've used the following construct for indexed, single-row
retrievals:
$sh = $dbh->prepare("select col from tbl where key = ?");
$sh->execute();
@ar = $sh->fetchrow_array();
if ($#ar > -1) {...
I got bit today by a problem either in ADO.pm (2.96) or ADO itself.
Very small sample program to reproduce problem:
#!/usr/bin/perl -w
use DBI;
use strict;
$|++;
my $wbh = DBI->connect("dbi:ADO:Provider=SQLOLEDB;Data Source=localhost;Initial Catalog=db", 'user', 'pass', { RaiseError => 0, PrintError => 0 });
die "connect failed: " . DBI::errstr . "\n" if ! $wbh;
my $sh = $wbh->prepare("select int_prod_num, prod_num, whseloc from ProductXRef where prod_num = ? and whseloc = ?");
$sh->trace(9);
print "\nexec 7861700\n\n";
my $r = $sh->execute('7861700','7'); # row does not exist
print "\n\nfetch 7861700\n\n";
my @ar = $sh->fetchrow_array();
print "\n\nexec 720021448\n\n";
$r = $sh->execute('720021448','8'); # row does not exist
# however 7200214,8 DOES exist
print "\n\nfetch 720021448\n\n";
my @br = $sh->fetchrow_array();
print "\nfailed\n\n" if ($br[1] && $br[1] ne '720021448');
print "\n\ndisco\n";
$wbh->disconnect();
My problem is, the second fetch returns the wrong row
(prod_num=7200214). In the program that does the meaningful work, I
have a check to see if the row doesn't exist (by looking at $#br), but
that succeeds, with the wrong data. A subsequent update statement (on
a different handle) then fails because the row is not in the table.
During testing, if I comment out the first fetch, the second fails
properly. My workaround is to change my coding style from
$sh->execute();
my @ar = $sh->fethcrow_array();
to
if ($sh->execute() != 0) {
my @ar = $sh->fetchrow_array();
}
But, I don't think the correct behavior is to return the wrong row.
It looks like (just a guess) that the size of bind_param 1 is getting
truncated during the failed first call, but the below trace doesn't
show that happening.
If I get any extra time (this took long enough to track down) I'll
play with { ado_size => 9 } as a bind_param.
Trace and more details follow.
TIA,
Dave
schema:
CREATE TABLE [dbo].[ProductXRef] (
[prod_num] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[whseloc] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[int_prod_num] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY]
GO
CREATE UNIQUE CLUSTERED INDEX [pk_intxref] ON [dbo].[ProductXRef]([prod_num], [whseloc]) WITH FILLFACTOR = 90 ON [PRIMARY]
GO
CREATE UNIQUE INDEX [ix_productxref] ON [dbo].[ProductXRef]([whseloc], [int_prod_num]) WITH FILLFACTOR = 90 ON [PRIMARY]
GO
Data: neither of the two requested rows exist in the table. The only
one that exists is the tuple ('7200214','8',NULL).
SQL Server Version 8.00.760 (SP3).
I don't know how to tell which version of ADO is installed on my
machines.
Duplicated on both XP-Pro SP3 and Windows 2003 SP1.
This is perl, v5.8.7 built for MSWin32-x86-multi-thread
(with 14 registered patches, see perl -V for more detail)
DBI::st=HASH(0x1b2e76c) trace level set to 0x0/9 (DBI @ 0x0/0) in DBI 1.53-ithread (pid 2928)
exec 7861700
-> execute for DBD::ADO::st (DBI::st=HASH(0x1b2e394)~0x1b2e76c '7861700' '7') thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1105 via at p1.pl line 12
1 <> FETCH= 'select int_prod_num, prod_num, whseloc from ProductXRef where prod_num = ? and whseloc = ?' ('Statement' from cache) at C:/perl/site/lib/DBD/ADO.pm line 1105 via at p1.pl line 12
>> bind_param DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima1 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 12
1 -> bind_param for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 1 '7861700') thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1065
2 <> FETCH= 2 ('NUM_OF_PARAMS' from cache) at C:/perl/site/lib/DBD/ADO.pm line 1065
>> trace_msg DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @3 g0 ima5 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1091
2 -> trace_msg in DBD::_::common for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER ' -- Type : 200 7
' 5) thr#2247b4
-- Type : 200 7
2 <- trace_msg= 1 at C:/perl/site/lib/DBD/ADO.pm line 1091
1 <- bind_param= 1 at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 12
>> bind_param DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima1 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 12
1 -> bind_param for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 2 '7') thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1065
2 <> FETCH= 2 ('NUM_OF_PARAMS' from cache) at C:/perl/site/lib/DBD/ADO.pm line 1065
>> trace_msg DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @3 g0 ima5 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1091
2 -> trace_msg for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER ' -- Type : 200 1
' 5) thr#2247b4
-- Type : 200 1
2 <- trace_msg= 1 at C:/perl/site/lib/DBD/ADO.pm line 1091
1 <- bind_param= 1 at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 12
>> STORE DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima41c pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1186 via at p1.pl line 12
1 -> STORE for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'Statement' 'select int_prod_num, prod_num, whseloc from ProductXRef where prod_num = ? and whseloc = ?') thr#2247b4
1 <- STORE= 'select int_prod_num, prod_num, whseloc from ProductXRef where prod_num = ? and whseloc = ?' at C:/perl/site/lib/DBD/ADO.pm line 1186 via at p1.pl line 12
>> STORE DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima41c pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1187 via at p1.pl line 12
1 -> STORE for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'NUM_OF_FIELDS' 3) thr#2247b4
STORE DBI::st=HASH(0x1b2e76c) 'NUM_OF_FIELDS' => 3
1 <- STORE= 1 at C:/perl/site/lib/DBD/ADO.pm line 1187 via at p1.pl line 12
>> STORE DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima41c pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1188 via at p1.pl line 12
1 -> STORE for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'Active' 1) thr#2247b4
STORE DBI::st=HASH(0x1b2e76c) 'Active' => 1
1 <- STORE= 1 at C:/perl/site/lib/DBD/ADO.pm line 1188 via at p1.pl line 12
<- execute= '0E0' at p1.pl line 12
fetch 7861700
-> fetchrow_array in DBD::_::st for DBD::ADO::st (DBI::st=HASH(0x1b2e394)~0x1b2e76c) thr#2247b4
>> fetch DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/1 @1 g0 ima0 pid#2928) at p1.pl line 14
1 -> fetch for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER) thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1209 via at p1.pl line 14
2 -> FETCH for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'Active') thr#2247b4
.. FETCH DBI::st=HASH(0x1b2e76c) 'Active' = 1
2 <- FETCH= 1 at C:/perl/site/lib/DBD/ADO.pm line 1209 via at p1.pl line 14
>> finish DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @1 g0 ima1 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1216 via at p1.pl line 14
2 -> finish for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER) thr#2247b4
2 <- finish= 1 at C:/perl/site/lib/DBD/ADO.pm line 1216 via at p1.pl line 14
1 <- fetch= undef row-1 at p1.pl line 14
<- fetchrow_array= ( ) [0 items] row-1 at p1.pl line 14
exec 720021448
-> execute for DBD::ADO::st (DBI::st=HASH(0x1b2e394)~0x1b2e76c '720021448' '8') thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1105 via at p1.pl line 16
1 <> FETCH= 'select int_prod_num, prod_num, whseloc from ProductXRef where prod_num = ? and whseloc = ?' ('Statement' from cache) at C:/perl/site/lib/DBD/ADO.pm line 1105 via at p1.pl line 16
>> bind_param DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima1 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 16
1 -> bind_param for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 1 '720021448') thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1065
2 <> FETCH= 2 ('NUM_OF_PARAMS' from cache) at C:/perl/site/lib/DBD/ADO.pm line 1065
>> trace_msg DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @3 g0 ima5 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1091
2 -> trace_msg for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER ' -- Type : 200 9
' 5) thr#2247b4
-- Type : 200 9
2 <- trace_msg= 1 at C:/perl/site/lib/DBD/ADO.pm line 1091
1 <- bind_param= 1 at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 16
>> bind_param DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima1 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 16
1 -> bind_param for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 2 '8') thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1065
2 <> FETCH= 2 ('NUM_OF_PARAMS' from cache) at C:/perl/site/lib/DBD/ADO.pm line 1065
>> trace_msg DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/3 @3 g0 ima5 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1091
2 -> trace_msg for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER ' -- Type : 200 1
' 5) thr#2247b4
-- Type : 200 1
2 <- trace_msg= 1 at C:/perl/site/lib/DBD/ADO.pm line 1091
1 <- bind_param= 1 at C:/perl/site/lib/DBD/ADO.pm line 1111 via at p1.pl line 16
>> STORE DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima41c pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1186 via at p1.pl line 16
1 -> STORE for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'Statement' 'select int_prod_num, prod_num, whseloc from ProductXRef where prod_num = ? and whseloc = ?') thr#2247b4
1 <- STORE= 'select int_prod_num, prod_num, whseloc from ProductXRef where prod_num = ? and whseloc = ?' at C:/perl/site/lib/DBD/ADO.pm line 1186 via at p1.pl line 16
>> STORE DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima41c pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1187 via at p1.pl line 16
1 -> STORE for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'NUM_OF_FIELDS' 3) thr#2247b4
1 <- STORE= 3 at C:/perl/site/lib/DBD/ADO.pm line 1187 via at p1.pl line 16
>> STORE DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @3 g0 ima41c pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1188 via at p1.pl line 16
1 -> STORE for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'Active' 1) thr#2247b4
STORE DBI::st=HASH(0x1b2e76c) 'Active' => 1
1 <- STORE= 1 at C:/perl/site/lib/DBD/ADO.pm line 1188 via at p1.pl line 16
<- execute= -1 at p1.pl line 16
fetch 720021448
-> fetchrow_array for DBD::ADO::st (DBI::st=HASH(0x1b2e394)~0x1b2e76c) thr#2247b4
>> fetch DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/1 @1 g0 ima0 pid#2928) at p1.pl line 18
1 -> fetch for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER) thr#2247b4
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1209 via at p1.pl line 18
2 -> FETCH for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'Active') thr#2247b4
.. FETCH DBI::st=HASH(0x1b2e76c) 'Active' = 1
2 <- FETCH= 1 at C:/perl/site/lib/DBD/ADO.pm line 1209 via at p1.pl line 18
>> FETCH DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @2 g0 ima404 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1251 via at p1.pl line 18
2 -> FETCH for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER 'ChopBlanks') thr#2247b4
.. FETCH DBI::st=HASH(0x1b2e76c) 'ChopBlanks' = ''
2 <- FETCH= '' at C:/perl/site/lib/DBD/ADO.pm line 1251 via at p1.pl line 18
>> _set_fbav DISPATCH (DBI::st=HASH(0x1b2e76c) rc1/2 @2 g0 ima0 pid#2928) at C:/perl/site/lib/DBD/ADO.pm line 1254 via at p1.pl line 18
2 -> _set_fbav in DBD::_::st for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER ARRAY(0x1b2d290)) thr#2247b4
dbih_setup_fbav for 3 fields => 0x1b2efdc
2 <- _set_fbav= [ undef '7200214' '8' ] at C:/perl/site/lib/DBD/ADO.pm line 1254 via at p1.pl line 18
1 <- fetch= [ undef '7200214' '8' ] row1 at p1.pl line 18
<- fetchrow_array= ( undef '7200214' '8' ) [3 items] row1 at p1.pl line 18
failed
disco
-> DESTROY for DBD::ADO::st (DBI::st=HASH(0x1b2e76c)~INNER) thr#2247b4
<- DESTROY= undef