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

Fellow Monks,

I have an issue here using Win32::ODBC to get multiple queries from the same database or a different one. I originally tried to get fields from seperate tables, but now I have it doing the same exact query twice, just to illustrate that it doesn't work when I do the second query, but if I do just the first query I do get the expected data. Can anybody see anything here that might prevent my program from returning the results from the second query? Thanks

bW

#!/opt/perl/bin/perl use Win32::ODBC; use strict; my $outdir="//Cmdsrv02/EPIC_Users/Group_Share/Database/meetings/script +s/"; #MAKE CONNECTION AND QUERY ACCESS DATABASE my $connstring = "DRIVER=Microsoft Access Driver (*.mdb);DBQ=//Cmdsrv0 +2/EPIC_Users/Group_Share/Contacts/contacts.mdb"; my $db = new Win32::ODBC($connstring); $db->Sql("SELECT * FROM groups_in_disciplines"); #OPEN EXTERNAL LOGFILE open(LOGFILE, ">$outdir/events.txt"); while ($db->FetchRow()) { my $discipline_id = "discipline_id"; my $discipline = "discipline_id"; $discipline_id=$db->Data($discipline_id); my $db2 = new Win32::ODBC($connstring); $db2->Sql("SELECT * FROM groups_in_disciplines"); while ($db2->FetchRow()) { $discipline = $db2->Data($discipline); print LOGFILE $discipline, " "; # $discipline_id works } $db2->Close(); } close LOGFILE; $db->Close(); exit;

Replies are listed 'Best First'.
Re: Win32::ODBC Multiple Queries
by Nitrox (Chaplain) on Dec 18, 2002 at 17:39 UTC
    I would suggest not opening your second database connection from inside the while() loop.

    Also, if your end goal is to get the results for multiple queries I'd suggest looking into SQL syntax, specifically join's.

    -Nitrox

      Thanx Nitrox, turns out I was moving the iterator($db2->Data()) out of the second while loop. This caused it not to output anything. Another case of programmer error!

      So that error being fixed, I tryed to tie 3 quieries together like so but now I'm getting a Runtime Error. I get the first value to print out and then I get that dreaded Runtime Error. Is it possible that I'm exceding a buffer or something? Can anybody explain why that could happen? Thanks again!

      #!/opt/perl/bin/perl use Win32::ODBC; use strict; my $outdir="//Cmdsrv02/EPIC_Users/Group_Share/Database/meetings/script +s/"; #MAKE CONNECTION AND QUERY ACCESS DATABASE my $connstring = "DRIVER=Microsoft Access Driver (*.mdb);DBQ=//Cmdsrv0 +2/EPIC_Users/Group_Share/Database/meetings/meetings.mdb"; my $connstring2 = "DRIVER=Microsoft Access Driver (*.mdb);DBQ=//Cmdsrv +02/EPIC_Users/Group_Share/Contacts/contacts.mdb"; my $db = new Win32::ODBC($connstring); my $db2 = new Win32::ODBC($connstring2); my $db3 = new Win32::ODBC($connstring2); $db->Sql("SELECT * FROM meetings INNER JOIN groups ON meetings.group_i +d=groups.group_id"); #OPEN EXTERNAL LOGFILE open(LOGFILE, ">$outdir/events.txt"); while ($db->FetchRow()) { #DB Variables my $meeting_id="meeting_id", my $meeting_type_id="meeting_type_id", my + $group_id="group_id", my $group_name="group_name", my $contact1_id=" +contact1_id", my $contact2_id="contact2_id", my $title="title", my $d +etails="details", my $date_begin="date_begin", my $date_end="date_end +", my $time_begin="time_begin", my $time_end="time_end", my $duration +="duration", my $call_in_number="call_in_number", my $call_in_code="c +all_in_code", my $location="location", my $date_last_published="date_ +last_published", my $discipline="discipline"; my $discipline_id = "di +scipline_id"; my $discipline = "discipline"; $meeting_id=$db->Data($meeting_id); $meeting_type_id=$db->Data($meetin +g_type_id); $group_id=$db->Data($group_id); $group_name=$db->Data($gr +oup_name); $contact1_id=$db->Data($contact1_id); $contact2_id=$db->Da +ta($contact2_id); $title=$db->Data($title); $details=$db->Data($detai +ls); $date_begin=$db->Data($date_begin); $date_end=$db->Data($date_en +d); $time_begin=$db->Data($time_begin); $time_end=$db->Data($time_end +); $duration=$db->Data($duration); $call_in_number=$db->Data($call_in +_number); $call_in_code=$db->Data($call_in_code); $location=$db->Data +($location); $date_last_published=$db->Data($date_last_published); #INTERNAL QUERY $db2->Sql("SELECT discipline_id FROM groups_in_disciplines WHERE group +_id=$group_id"); $db2->FetchRow(); $discipline_id=$db2->Data($discipline_id); $db3->Sql("SELECT discipline FROM disciplines WHERE discipline_id=$dis +cipline_id"); $db3->FetchRow(); $discipline = $db3->Data($discipline); print LOGFILE $discipline, "\t"; #print LOGFILE $meeting_id, "\t"; #print LOGFILE $meeting_type_id, "\t"; #print LOGFILE $group_id, "\t"; #print LOGFILE $group_name, "\t"; #print LOGFILE $contact1_id, "\t"; #print LOGFILE $contact2_id, "\t"; #print LOGFILE $title, "\t"; #print LOGFILE $details, "\t"; #print LOGFILE $date_begin, "\t"; #print LOGFILE $date_end, "\t"; #print LOGFILE $time_begin, "\t"; #print LOGFILE $time_end, "\t"; #print LOGFILE $duration, "\t"; #print LOGFILE $call_in_number, "\t"; #print LOGFILE $call_in_code, "\t"; #print LOGFILE $location, "\t"; #print LOGFILE $date_last_published, "\n"; $db2->Close(); $db3->Close(); } close LOGFILE; $db->Close(); exit();

      bW

      Perl - the breakfast of Champions!

Re: Win32::ODBC Multiple Queries
by Tanalis (Curate) on Dec 18, 2002 at 18:02 UTC
    Heys,

    I'm reading between the lines here, but if you're simply trying to retrieve more than one field from the row (hence the second query) you might be interested in Win32::ODBC's DataHash method, which returns a hash keyed on column names of either all or specific columns from the query.

    For example, for the two columns you use above, you could use the following:

    while ($db->FetchRow()) { my %data = $db->DataHash("discipline_id", "discipline"); print LOGFILE join " ", $data{discipline_id}, $data{discipline}; }

    I'm not sure if that helps you in any way, though. I agree with Nitrox regarding taking a look at SQL - there's a couple good references out there - I usually use the Sybase docs, but if you can find some specifically for MS Access, then so much the better :)

    Hope that's some help..
    -- Foxcub

      I wrote an SQL query tool using Win32::ODBC and it worked great for DSN using mySQL and Sybase. But, when I tried to connect to a DSN using MSAccess, I got a Runtime Error too. I tried different versions of Win32::ODBC, and even created the same database, with exact same tablenames, column names and data types and it still failed. I ended up trying DBI, and DBI worked. If you look at DBI, you will notice that it handles placeholders and bind variables diffently than ODBC. Which may be part of the problem you are experiencing. Notice the difference in these two calls in DBI...
      if($query eq '*'){ $sth = $db->prepare("SELECT * FROM data ORDER BY[$orderkey]"); $sth->execute(); ... if($query eq $name ){ $sth = $db->prepare("SELECT ? FROM data order by [$orderkey]"); $sth->execute($name);
      The runtime error you are getting may have to do with how Access checks/binds the correct data types prior to executing the SQL. If the data type/size don't match up, the SQL won't execute. In short, if they other gent's suggestions didn't solve your problem... give DBI a try. And, I just started adding use strict; to ALL my scripts after getting hollered at enough... and it really helps :)