http://www.perlmonks.org?node_id=1060016

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

Hi, I have written following perl code:
#!C:/Perl64/bin/perl.exe use DBI; use CGI; $cgi = new CGI; ##Create table using cgi $dbh = DBI->connect("dbi:mysql:TestDB", 'root','zulfi12345') or die "U +nable to connect: $DBI::errstr\n"; $username = $cgi->param( 'username' ) || ''; $password = $cgi->param ('password') || ''; $submit = $cgi->param( 'submit' ) || ''; $sth = $dbh->prepare("SELECT username, password FROM users WHERE usern +ame =$username and password=$password"); $sth->execute(); $found=0; while($row = $sth->fetchrow_hashref) { $found=1; } if ($found==1){ print "Welcome";}
Its giving me following error: Quote D:\Zulfi\PERL MAIN FOLDER>perl login.pl DBD::mysql::st execute failed: You have an error in your SQL syntax; check the m anual that corresponds to your MySQL server version for the right syntax to use near 'and password=' at line 1 at login.pl line 15. DBD::mysql::st fetchrow_hashref failed: fetch() without execute() at login.pl li ne 17. /QUOTE Somebody plz help me in this regard. Zulfi.

Replies are listed 'Best First'.
Re: problem with login script
by ig (Vicar) on Oct 28, 2013 at 18:13 UTC

    It will be easier for you to find the error if you can see the SQL that your program attempts to run. There are many ways to do this. One is to use the RaiseError option of DBI to "force errors to raise exceptions rather than simply return error codes in the normal way", then use eval to catch the exception and display the SQL and parameters. Something like the following:

    #!C:/Perl64/bin/perl.exe use strict; use warnings; use DBI; use CGI; my $cgi = new CGI; ##Create table using cgi $dbh = DBI->connect( "dbi:mysql:TestDB", 'root','zulfi12345', { RaiseError => 1, } ) or die "Unable to connect: $DBI::errstr\n"; my $username = $cgi->param( 'username' ) || ''; my $password = $cgi->param ('password') || ''; my $submit = $cgi->param( 'submit' ) || ''; my $sth = $dbh->prepare(" SELECT username, password FROM users WHERE username = ? and password = ? "); my @values = ($username, $password); eval { $sth->execute(@values); }; if($@) { die "Execution of\n" . $sth->{Statement} . "\n" . "with: @values\n" . "failed with: $@\n "; } my $found=0; while(my $row = $sth->fetchrow_hashref) { $found=1; } if ($found==1) { print "Welcome"; }

    I have made a few other changes here that you might consider for your own code:

    I added use strict; and use warnings;. These are not relevant to your immediate problem but I use them generally and suggest you do too. You can read more about them at Use strict and warnings and elsewhere.

    Because I added use strict;, I also added my to declare variables as lexically scoped. There are other ways to conform to the "strict" constraints, but this is an easy one to get started that usually does what I want (and probably you too) and you can learn and use the others as need arises.

    I have used Placeholders and Bind Values in the SQL statement. This avoids the need to escape 'special' characters in the values in your SQL. This helps to avoid 'SQL injection', which you should learn about.

Re: problem with login script
by toolic (Bishop) on Oct 28, 2013 at 17:26 UTC
Re: problem with login script
by ww (Archbishop) on Oct 28, 2013 at 17:32 UTC
    Just do what the error message advises beginning at "check the...." Read the MySQL docs -- probably online and easily found with a naive search for "MySQL" and "error". This is a matter of self-study and learning SQL syntax; not a Perl question.

    If you fix that, the second part of the message just might go away.

Re: problem with login script
by marinersk (Priest) on Oct 28, 2013 at 18:53 UTC
    Two suggestions.

    1. Change:
      #!C:/Perl64/bin/perl.exe
      use DBI;

      to

      #!C:/Perl64/bin/perl.exe
      use strict;
      use warnings;
      use DBI;

      and;
       

    2. Change:
      $sth = $dbh->prepare("SELECT username, password FROM users WHERE username =$username and password=$password");

      to

      my $sqlStatement = "SELECT username, password FROM users WHERE username =$username and password=$password";
      print "Submitting:  $sqlStatement\n";
      $sth = $dbh->prepare($sqlStatement);

       

    See what the full SQL statement looks like; you are likely to find an error there, since that's what your error message says.

    Most SQL requires strings to be encapsulated in single-quotes:  ... and password = 'newpassword';

    Dunno if that's your problem, but the above changes should help shed light on what you are getting wrong in the SQL statement.

Re: problem with login script
by Anonymous Monk on Oct 28, 2013 at 18:09 UTC
    Congratulations on writing a login script highly vulnerable to SQL injection, btw!

      Perhaps what you were trying to say is "You should learn about SQL injection." It is a serious security vulnerability that is easy to avoid, once you know how.