Perl
  Home arrow Perl arrow Page 2 - SQL and CGI with Perl and DBI
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
Google.com  
PERL

SQL and CGI with Perl and DBI
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 4
    2008-04-03


    Table of Contents:
  • SQL and CGI with Perl and DBI
  • A More Complex Example
  • Use Placeholders
  • DBI and Table Joins
  • Perl DBI CGI = Fun!
  • What We Didn’t Talk About

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    SQL and CGI with Perl and DBI - A More Complex Example
    ( Page 2 of 6 )

    Remember the complex query we did previously in this chapter when we tried to find out the instruments played by Lenny Kravitz? It was a three-step process: first, we found his player_id from the musicians table. Then we used that player_id to read the inst_id s from the what_they_play table. For each of those inst_id s, we read the instrument name from the instruments table. Here is how we might do this in Perl and DBI :

    #!/usr/bin/perl -w
    # showinstruments1.pl

    use strict;
    use DBI;

    my($who, $player_id, $inst_id);

    print "Enter name of musician and I will show you his/her instruments: ";
    chomp($who = <STDIN>);

    my $dbh = DBI->connect("DBI:mysql:musicians_db", "musicfan", "CrimsonKing");

    die "connect failed: " . DBI->errstr() unless $dbh;

    # first, grab the musicians player_id
    my $sth = $dbh->prepare("SELECT player_id FROM musicians WHERE name = '$who'")
                 or die "prepare failed: " . $dbh->errstr();

    $sth->execute() or die "execute failed: " . $sth->errstr();

    ($player_id) = $sth->fetchrow();

    die "player_id not found" unless defined $player_id;

    # given the player_id, grab their inst_ids from what_they_play
    $sth = $dbh->prepare("SELECT inst_id FROM what_they_play
                                 WHERE player_id = $player_id")
                 or die "prepare failed: " . $dbh->errstr();

    $sth->execute() or die "execute failed: " . $sth->errstr();

    # foreach inst_id, grab the instrument name from th e
    # instruments table and print it
    while (($inst_id) = $sth->fetchrow()) {
        my $sth = $dbh->prepare("SELECT instrument FROM instruments
                                         WHERE inst_id = $inst_id")
                 or die "prepare failed: " . $dbh->errstr();

        $sth->execute() or die "execute failed: " . $sth->errstr();

        my($instrument) = $sth->fetchrow();
        print "    $instrument\n";

        $sth->finish();
    }

    $sth->finish();

    $dbh->disconnect();

    Let’s look at each step of this process. After connecting to the database as we have been doing in the previous examples and asking for the user to enter the name of a musician, we construct and execute a query to obtain that musician’s player_id .

    # first, grab the musicians player_id
    my $sth = $dbh->prepare("SELECT player_id FROM musicians WHERE name = '$who'")
                 or die "prepare failed: " . $dbh->errstr();

    $sth->execute() or die "execute failed: " . $sth->errstr();

    ($player_id) = $sth->fetchrow();

    die "player_id not found" unless defined $player_id;

    Notice how the SQL query is constructed using the variable $who . The outer double quotes of the query string are needed to take the value of $who . The SQL query needs to quote the name since it is a string, so wrapped around $who within the query are single quotes.

    The query is then executed. This should return only one row (it could return zero rows if the musician is not found in the table) so we only have to call fetchrow() once—we take the return value of that method, a list of one value, and assign it to the assignable list ($player_id) . The result is that $player_id will be the player_id of the musician that the user entered at standard input or undef if the musician was not found. The program die() s if $player_id is not defined.

    Then we use $player_id and construct a query asking for the inst_id s:

    # given the player_id, grab their inst_ids from what_they_play
    $sth = $dbh->prepare("SELECT inst_id FROM what_they_play
                                 WHERE player_id = $player_id")
                 or die "prepare failed: " . $dbh->errstr();

    $sth->execute() or die "execute failed: " . $sth->errstr();

    Notice how the query string contains $player_id , the value we just read out of the data base. Since the player_id is an integer, it does not need to be quoted within the SQL query. When executed, this should return back all the inst_id s for that player_id . We then loop through the result, each row at a time:

    # foreach inst_id, grab the instrument name from the
    # instruments table and print it
    while (($inst_id) = $sth->fetchrow()) {
       
    my $sth = $dbh->prepare("SELECT instrument FROM instrument s
                                        WHERE inst_id = $inst_id")
           or die "prepare failed: " . $dbh->errstr();

        $sth->execute() or die "execute failed: " . $sth->errstr();

        my($instrument) = $sth->fetchrow();
        print "    $instrument\n";

        $sth->finish();
    }

    As we loop through each row of output from the previous query, we prepare() another query to read the name of the instrument from the instruments table. Notice that within the while loop, $sth will receive the return value from prepare() and that we have declared this variable with a my() . The my() here is very important—it creates a new copy of $sth within the while loop so we will not clobber the previous value of $sth outside the while loop (the result of the query of the what_they_play table). If we had not declared $sth with a my() , that previous query would have been overwritten and we would have only processed one row of output from the query of what_they_play . An alternative to declaring $sth with my() would have been selecting a different variable name, which would have been fine, but sticking with $sth as the state handler variable is the convention (besides, that new variable would have to have been my() ed as well).

    Executing the program looks like this:

    $ perl showinstruments1.pl
    Enter name of musician and I will show you his/her instruments: Roger Waters
       
    guitar
        vocals
    $

    Excellent! But, not so fast. There is a problem with this program, demonstrated with this example:

    $ perl showinstruments1.pl
    Enter name of musician and I will show you his/her instruments: Chris O'Rourke DBD::mysql::st execute failed: You have an error in your SQL syntax near
    'Rourke'' at line 1 at showinstruments1.pl line 20, <STDIN> line 1.
    execute failed: You have an error in your SQL syntax near 'Rourke'' at line 1 at showinstruments1.pl line 20, <STDIN> line 1. $

    Can you see what the problem is? The query that uses $who , the name entered, looks like this:

    $dbh->prepare("select player_id from musicians where name = '$who'")

    Since $who is single-quoted in the SQL query string, the single quote in the name “Chris O’Rourke” makes SQL think that the string it is comparing to name is “Chris O”. SQL then sees “Rourke”, which is totally out of place—this is a syntax error.

    You may think the answer is to escape the single quote and turn $who into “Chris O\’Rourke”. This is possible, and would work, but there is a better way.



     
     
    >>> More Perl Articles          >>> More By Apress Publishing
     

       

    PERL ARTICLES

    - More Perl Bits
    - Perl, Bit by Bit
    - Basic Charting with Perl
    - Using Getopt::Long: More Command Line Option...
    - Command Line Options in Perl: Using Getopt::...
    - Web Access with LWP
    - More Templating Tools for Perl
    - Site Layout with Perl Templating Tools
    - Build a Perl RSS Aggregator with Templating ...
    - Looping, Security, and Templating Tools
    - Perl: Bon Voyage Lists and Hashes
    - Templating Tools
    - Perl: Number Crunching
    - Perl Debuggers in Detail
    - Debugging Perl





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 6 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek