holandes777 has asked for the wisdom of the Perl Monks concerning the following question:

The following code executes a lengthy (time consuming) stored procedure.
#!perl use strict; use DBI; $|=1; my %INI; $INI{DSN} = 'Casinfo-SQL'; $INI{DBuser} = 'sa'; $INI{DBpass} = 'diamond'; my $dbh; # database filehandle my $stmt; my $userid = 1; print "before connect\n"; if ( $dbh = DBI->connect("DBI:ODBC:$INI{DSN}",$INI{DBuser},$INI{DBpass +}) ) { $dbh->{AutoCommit} = 0; # enable transactions, if possible $dbh->{RaiseError} = 1; print "connected\n"; eval { my $stmt = "exec sp3PTSdrawing $userid"; print "before |$stmt|\n"; my $success = sDB_EXEC($stmt,$dbh); $dbh->commit; print "commited\n"; }; if ($@) { warn "Transaction aborted because $@"; eval { $dbh->rollback }; print "rolled back\n"; } $dbh->disconnect(); print "disconnecting\n"; } else { print "ERROR:Could not connect to database (ODBC DSN) |$INI{DSN}| $ +DBI::errstr \n"; } # end if ( $dbh = DBI->connect("DBI:ODBC:$INI{DSN}",$INI{DBuser},$IN +I{DBpass}) ) ###################################################################### +#### sub sDB_EXEC { my $stmt = $_[0]; my $dbh = $_[1]; my $debugthreshhold = 2; my $rc; # record count of lines inserted if ( $rc = $dbh->do($stmt) ) { print "IN sDB_EXEC: $stmt RETURNS $rc\n"; } else { print "ERROR: could not |$stmt| error|$DBI::err|$DBI::errstr and + |$!|\n"; } return $rc; }
When
exec sp3PTSdrawing 1
is executed from the Query Analyzer the procedure takes between 30 seconds and 2 minutes. It completes with lots of records being written to a table.
 
When the perl program is executed from the command prompt it takes about 8 seconds. The output of the program is as follows:
before connect connected before |exec sp3PTSdrawing 1| IN sDB_EXEC: exec sp3drawing 1 RETURNS 1 commited disconnecting
However, the resulting set of records is incomplete. It is as if the execution timed out but was still deemed OK. The partial record set is committed to the database.
 
In reading through the DBI there is code to allow the user to abort a transaction, but I don't see code to set maximum timeout limits. I thought it might be an ODBC timeout, but I see no timeouts in the ODBC setup, plus I have long running queries in perl scripts on this server (longer than 30 seconds).
 
Advice would be greatly appreciated.

Replies are listed 'Best First'.
Re: DBI - ODBC- do - MSSQL stored procedure - does not complete but returns "ok"
by Devanchya (Beadle) on Dec 15, 2006 at 16:28 UTC
    At this second I can not delve into the DBI code itself, but I believe there is a MSSQL option to set the timeout of a client connection.

    What is happening, by the sounds of it, is the DBI is dropping the connection, your program sees the drop and continues. Your line in the eval: $dbh->commit; will commit the code even if it completely screwed up. Your not checking to see if it was a success before commiting.

    In SYBASE you can extend the time out using the dbi:Sybase:timeout=240 connector. In MYSQL you can use the mysql_connect_timeout=240 in the connector like sybase.
    I do not see this option in MSSQL, but my knowledge there is lacking a bit.

    Hope this helps, and isn't a complete waste of space.
    --

    Even smart people are dumb in most things...