I don't use ADO but I do use ODBC. SQL Server normally batches the statements in a procedure so in ODBC terms for your procedure you have to:
execute fetchall SQLMoreResults # moves to the update rowcount - to get row update count SQLMoreResults - # moves to the second select fetchall SQLMoreResult - returns SQL_NO_DATA DBD::ODBC used to have a lot of problems with procedures like this including hitting an issue in the MS SQL Server driver which would return invalid cursor state when prepare/execute was used but worked fine with SQLExecDirect. My guess (and it is a guess only) is that DBD::ADO has pulled the rows from the first result-set and knows there is nothing more (hence handle not active) because it has not done the equivalent of SQLMoreResults. Of course, for I know DBD::ADO has a more results method. BTW, DBD::ODBC calls SQLMoreResults automatically for you sometimes. Basically if SQLNumResultCols returns 0 then the last statement was an insert/update/delete so it calls SQLMoreResults for you. If SQLNumResultCols returns > 0 then there is a result-set and you have to use odbc_more_results method to move on. DBD::DB2 also had an equivalent of odbc_more_results. Martin -- Martin J. Evans Easysoft Ltd, UK Development On 01-Mar-2005 David N Murray wrote: > Hi all, > > Since we seem to be on the subject of Stored Procedures, I thought > I'd throw my problem out there, since I can't figure out what I'm > doing wrong. > > The SP builds a temp table, updates the source table from the temp > table and then returns a recordset with the contents of the temp > table. > > The error I'm getting is 'statement handle not active' on the fetchrow_array > call. The update statement executes. > > What I find interesting is that the execute returns the number of rows > affected (per the docs). I wonder if that is what's killing the > fact that I have a recordset there, too. > > I realize I'm probably missing something obvious. Thanks in advance. > > Dave > > This is SQL Server 2000, DBI 1.43, DBD::ADO 2.91, all on XP: > > create procedure p > @p int > as > select top 10 c1, c2 > into #tmp > from t > where c3 = @p > update t > set c4 = 1 > from t, #tmp t2 > where t.c1 = t2.c1 > select c1, c2 > from #tmp > order by c2, c1 > go > > and the perl that runs this (I removed the error handling for brevity): > >#!/usr/bin/perl -w > use DBI; > use strict; > my $dbh = DBI->connect("dbi:ADO:Provider=SQLOLEDB;Data Source=(local);Initial > Catalog=db", "user","pass"); > die "Connect failed: " . $DBI::errstr if (!defined $dbh); > > my $sh = $dbh->prepare("p 1"); > $sh->trace(3); > $sh->execute(); > while (my @ar = $sh->fetchrow_array()) { > print join(":", @ar), "\n"; > } > $dbh->disconnect; > > The trace: > DBI::st=HASH(0x1a5d8e0) trace level set to 0x0/3 (DBI @ 0x0/0) in DBI > 1.43-i > thread (pid 2552) > -> execute for DBD::ADO::st (DBI::st=HASH(0x1a5d5a4)~0x1a5d8e0) > thr#22433c > 1 <> FETCH= 'p 1' ('Statement' from cache) at ADO.pm line 1338 via t.pl > line 1 > 0 > <- execute= 10 at t.pl line 10 > -> fetchrow_array in DBD::_::st for DBD::ADO::st > (DBI::st=HASH(0x1a5d5a4)~0x > 1a5d8e0) thr#22433c > 1 -> fetch for DBD::ADO::st (DBI::st=HASH(0x1a5d8e0)~INNER) thr#22433c > 2 -> FETCH for DBD::ADO::st (DBI::st=HASH(0x1a5d8e0)~INNER 'Active') > thr#22433 > c > .. FETCH DBI::st=HASH(0x1a5d8e0) 'Active' = '' > 2 <- FETCH= '' at ADO.pm line 1468 via t.pl line 12 > 2 -> set_err in DBD::_::common for DBD::ADO::st > (DBI::st=HASH(0x1a5d8e0)~INNER > -900 'Statement handle not marked as Active.') thr#22433c > !! ERROR: -900 'Statement handle not marked as Active.' (err#1) > 2 <- set_err= undef at ADO.pm line 1468 via t.pl line 12 > !! ERROR: -900 'Statement handle not marked as Active.' (err#1) > 1 <- fetch= undef row-1 at t.pl line 12 > !! ERROR: -900 'Statement handle not marked as Active.' (err#1) > <- fetchrow_array= ( ) [0 items] row-1 at t.pl line 12 > DBD::ADO::st fetchrow_array failed: Statement handle not marked as Active. at > t. > pl line 12. > -> DESTROY for DBD::ADO::st (DBI::st=HASH(0x1a5d8e0)~INNER) thr#22433c > -> finish for DBD::ADO::st (DBI::st=HASH(0x1a5d8e0)~INNER) thr#22433c > <- finish= 1 at ADO.pm line 1542 via t.pl line 0 > <- DESTROY= undef