Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

MS SQL problem

by Win (Novice)
on Dec 10, 2004 at 16:38 UTC ( [id://413899]=perlquestion: print w/replies, xml ) Need Help??

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

Dear Monks,

Has anyone had experience of the following error message:
DBD::ODBC::st execute failed: [Microsoft][ODBC SQL Server Driver]Conne +ction is busy with results for another hstmt (SQL-HY000)(DBD:st_execu +te/SQLExecute err=-1) at 20_October_2004_K.pl line 209, <FLAT_FILE> l +ine 29.
I get it when running the following bit of code. It is a problem that I did not have earlier. But now I am activating this code in a different way.
sub Got_Command { my($Command,$Request_id, $outputfile) = @_; print "Hi_F\n"; print "here\n"; # my $output_file = "Output/Output_file_".$Request_id.".txt"; open (OUTPUT_FILE, ">$outputfile"); print "$Command\n"; my $sthB_A = $dbh->prepare($Command) or die "Couldn't prepare query +: ".$dbh->errstr; $sthB_A->execute() or die "Couldn't execute query: ".$sthB_A->errstr +; my $Return_results = "Select * from Result_storage_keep where Unique +_identifier = ".$Request_id." AND Aggregated_area = Instance_name AND + Disease_cat = Cause_catagory\;"; print "$Return_results"; print "$Return_results\n"; my $sth_C = $dbh->prepare($Return_results) or die "Couldn't prepare +query: ".$dbh->errstr; $sth_C->execute() or die "Couldn't execute query: ".$sth_C->errstr; ####The problem shows up here while (my @row = $sth_C->fetchrow_array ) { print OUTPUT_FILE join("\t", @row); print OUTPUT_FILE "\n"; } }
Can anyone please suggest improvements to this code?

Replies are listed 'Best First'.
Re: MS SQL problem
by dragonchild (Archbishop) on Dec 10, 2004 at 16:42 UTC
    Try adding the following line:
    my $sthB_A = $dbh->prepare($Command) or die "Couldn't prepare query: ".$dbh->errstr; $sthB_A->execute() or die "Couldn't execute query: ".$sthB_A->errstr +; #### $sthB_A->finish(); #### my $Return_results = "...";

    Certain DBD::* modules cannot handle more than one open sth for a given dbh. I've never run into it, but I've heard of some who have.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      dragonchild is correct.

      Funny thing is I was just reading about this last night in my "Programming the Perl DBI" book. It says if a statement handle is opened and has not been "finished" you will get the following warning when trying to reuse the statement handle: "disconnect invalidates 1 active statement handle (either destroy statement handles or call finish on them before disconnecting)". If you are fetching from a statement handle and you fetch the last row, the finish method is called for you. On the other hand if you do not fetch all the rows and try to reuse the statement handle you get the following warning: "disconnect invalidates 1 active statement handle (either destroy statement handles or call finish on them before disconnecting)".

      What I didn't read in the book is this. If you attempt to reuse the database handle when a statement handle is open and not finished you get the error: "st execute failed: [Microsoft][ODBC SQL Server Driver]Connection is busy with results for another hstmt". This may only be the case with MS SQL, but I am not sure.

      When I executed equivalent code you posted with warnings turned on, I got both the error you posted and the warning I posted.

      Update: Put code tags around error message to fix output.

      DBD::Sybase is one of those, though it will normally fake it by opening additional database connections "under the covers".

      This is essentially a limitation of the TDS protocol that both Sybase and MS use.

      Michael

Re: MS SQL problem
by VSarkiss (Monsignor) on Dec 10, 2004 at 16:48 UTC

    This is a pure guess without knowing what $Command contains, but....

    Since you're not fetching results after the first execute, I'm guessing you're not expecting any (an insert or update or some such). In that case, you can use $dbh->do($Command) instead of prepare/execute, which will make sure the connection is ready for the next query.

    Also, since you say it used to work, the change may let you see whether the command is returning a result set unexpectedly (such as if you're calling a stored procedure that has changed unbeknownst to you).

Re: MS SQL problem
by runrig (Abbot) on Dec 10, 2004 at 19:14 UTC
    Can anyone please suggest improvements to this code?

    You have your answer to the error, so I'll just mention that you can get rid of all those "or die ..." clauses in your DBI calls if you just set RaiseError during the connect. Plus you will get the added bonus of having error checking during the fetch, which you currently do not have.

Re: MS SQL problem
by flogic (Acolyte) on Dec 10, 2004 at 20:53 UTC

    Yeah MS SQL is special and doens't like to run multiple statements at once. I have a more general solution to the problem though.

    1. Rather than using a globals, I ask a special function for my DB handles. It handles it's own caching which is nice for MS SQL but probably redundant otherwise. If all the handles have $dbh->{Kids} set, then it creates a new handle otherwise it reuses an old one.

    2. I try hard to avoid having multiple SQL statements per subroutine. This ensures that there is one call to my special function per statement.

    The end result is I have to pay for connecting multple times. However I don't pay too much and my code feels cleaner.

Re: MS SQL problem
by edan (Curate) on Dec 15, 2004 at 13:22 UTC

    I think your problem is in this line:

    my $Return_results = "Select * from Result_storage_keep where Unique_i +dentifier = ".$Request_id." AND Aggregated_area = Instance_name AND D +isease_cat = Cause_catagory\;";

    It's really bad practice to use diseased cats in your code...

    --
    edan

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://413899]
Approved by VSarkiss
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-23 06:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found