I was not sure where to post it. Or whether to post it at all. But I think someone might find this helpfull.
This is not a question. It's a success report. A description of something that took me ages to fix. And to find the problem was not in Perl ... probably :-}
I have a service (daemon) that imports some XMLs into the database. The import procedure connects to the database using DBI+DBD::ODBC, reads the data using XML::RAX, loops through the objects, checks whether the object is already there (to choose between INSERT and UPDATE) and calls the appropriate stored procedure.
The problem was that suddenly this started to fail. As soon as there was something wrong with the data and the Insert or Update procedure raised an error all successive database calls returned "[Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt (SQL-HY000)(DBD: st_execute/SQLExecute err=-1)". I tried to add $stmt->finish() to the statement that returned the error. I tried to add $stmt->fetchall_arrayref() to make sure I read whatever could have been returned to me, I tried lots of other things, but nothing worked. And since I had to compile the script by PerlApp and upload it to the server half-the-globe away each test took at least 10 minutes (AAAAGGGRRR). Then I tried one last thing. I added SET NOCOUNT ON on top of the stored procedures because I remembered to had some problems in ASPs+ADO that were fixed by this and voila ... everything started to work. Without any finish()es or fetchall_arrayref()s. Not that I understand why, but ... thanks god I got it working at last.
I did NOT remove the statement from the SQL before it started to fail, but I may have updated DBI or DBD::ODBC. Currently I have ActivePerl 5.8 build 805, DBI 1.32 and DBD::ODBC 1.04.
The procedure that does the import looks somewhat like this:
and the procedures look like thissub importPublisher { my $file = shift(); my $time_started = time(); Log "\nImporting Publishers"; my ($new,$updated,$incorrect) = (0,0,0); my $PublisherId; my $check = $db->prepare('SELECT PublisherID FROM Publishers WHERE + MediaNumber = ? and CountryID = (SELECT CountryID FROM Country WHERE + Cname_advision = ?)'); db_error("compiling check Media number",$db) if !$check; my $insert = $db->prepare('EXEC InsertPublisher ?, ?, ?, ?, ?, ?, +?, ?, ?, ?, ?, ?'); db_error("compiling InsertPublisher",$db) if !$insert; my $update = $db->prepare('EXEC UpdatePublisher ?, ?, ?, ?, ?, ?, +?, ?, ?, ?, ?, ?'); db_error("compiling UpdatePublisher",$db) if !$update; my @fields = qw(publisher_name media_number address city state zip + phone contact fax email_id notes country); fixXML($file); my $reader = new XML::RAX; $reader->openfile($file) or die "Can't open $file: $!\n"; $reader->setRecord('PublisherData'); while (my $rec = $reader->readRecord()) { foreach (values %{$rec->{fields}}) {s/\n/ /g;s/^\s+//;s/\s+$// +;convText;undef $_ if $_ eq 'NULL'}; $rec->{fields}->{zip} =~ tr/-//d; unless (testFields($rec->{fields},$fields,"Publisher name '$re +c->{fields}->{publisher_name}'")) { $incorrect++; next; } my $res = $check->execute($rec->{fields}->{media_number}, $rec +->{fields}->{country}); if (!$res) { db_error("checking for Publisher '$rec->{fields}->{publish +er_name}', '$rec->{fields}->{country}'",$db,1); } elsif (abs($res) == 1) { $check->finish(); if ($update->execute(@{$rec->{fields}}{@fields})) { $updated++; } else { db_error("updating Publisher '$rec->{fields}->{publish +er_name}'",$db,1); $incorrect++; } } else { $check->finish(); if ($insert->execute(@{$rec->{fields}}{@fields})) { $new++; } else { db_error("inserting Publisher '$rec->{fields}->{publis +her_name}'",$db,1); $incorrect++; } } } LogNT "Imported $file with $new new, $updated updated and $incorre +ct incorrect records."; my $time_run = time() - $time_started; Log( sprintf "\tThe import took %02d:%02d:%02d HH:MM:SS",int($time +_run/3600),int($time_run/60) % 60, $time_run % 60); }
CREATE PROCEDURE InsertPublisherDetails( @publishername NAME, @medianumber varchar(50), @address ADDRESS, @city NAME, @state NAME, @zip ZIP, @phone PHONE, @contact NAME, @fax PHONE, @emailid EMAIL, @notes NOTES, @cname_advision varchar(2) ) AS BEGIN SET NOCOUNT ON -- this is what I had to add Declare @Country JdtID; SELECT @Country = CountryID FROM Country WHERE cname_advision = @ +cname_advision if @Country is NULL BEGIN raiserror('Cannot find the Country ''%s''!',11,1,@cname_advisi +on); RETURN; END INSERT INTO Publishers ( publishername, medianumber, address, city, state, zip, phone, contact, fax, emailid, notes ,CountryID ) values ( @publishername, @medianumber, @address, @city, @state, @zip, @pho +ne, @contact, @fax, @emailid, @notes, @Country ) RETURN @@identity END
Jenda
Always code as if the guy who ends up maintaining your code
will be a violent psychopath who knows where you live.
-- Rick Osborne
Edit by tye, untypoed closing CODE tag
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: MS SQL and "Connection is busy with results for another hstmt"
by mpeppler (Vicar) on Mar 28, 2003 at 16:44 UTC | |
|
Re: MS SQL and "Connection is busy with results for another hstmt"
by Solo (Deacon) on Mar 28, 2003 at 15:36 UTC |