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

Can anyone explain why I am recieving this error.
Use of uninitialized value in concatenation (.) or string at Signup.pl line 46.
Use of uninitialized value in string eq at Signup.pl line 52.
Use of uninitialized value in concatenation (.) or string at Signup.pl line 53.
Use of uninitialized value in concatenation (.) or string at Signup.pl line 60.
#Selecting parents name to identify as volunteer. if ($parent eq "Father") { $sub_parent = "Mother"; $sth = $dbh->prepare ("select Father from Roster where User = +\'$user\'"); $sth->execute (); $name = $sth->fetchrow_array; } #end if Father else { $sub_parent = "Father"; $sth = $dbh->prepare ("select Mother from Roster where User = +\'$user\'"); $sth->execute (); $name = $sth->fetchrow_array; } #end else Mother if ($name eq ""){ $sth = $dbh->prepare ("select $sub_parent from Roster where Us +er = \'$user\'"); $sth->execute (); $name = $sth->fetchrow_array; } #end chk for not parent if statement. print $query->h1({-align=>'center'},"THANK YOU FOR SIGNING UP $name"); foreach $date ( @volunteer_date ) { $sth = $dbh->prepare ("select distinct Volunteer from Voluntee +r where Volunteer = \'$name\' and Date = \'$date\'"); $sth->execute (); my $chk = $sth->fetchrow_array; if ($chk eq $name){ print $query->h1({-align=>'center'}, "You are already signed u +p for this date: $date"); } #end if statement else{ $sth = $dbh->prepare ("select max(Number) from Volunteer where Date = '$date' and Volunteer = 'TBD'"); $sth->execute ();

Replies are listed 'Best First'.
(Ovid) Re: uninitialized value in concatenation
by Ovid (Cardinal) on Jan 14, 2002 at 22:46 UTC

    mnlight wrote:

    Can anyone explain why I am recieving this error.
    Use of uninitialized value in concatenation (.) or string at Signup.pl line 46...

    The short answer is "yes, I can explain why." You have an unitialized value in a concatenation or string. The longer answer is, "no, I don't know why you have an unitialized value." I don't know what your line numbers are, so I can't tell where the value is. Further, while I could try to figure out the offsets from your error messages and correlate those to print statements in your code, I'm not going to do that.

    If you have a halfway decent editor (no, I'm not talking about Notepad), you should be able to see your line numbers. Since you're not using HERE docs (which can obscure the problem), you should be able to point almost perfectly to the line where you have an unitialized value. For example:

    $ perl -e ' use strict; use warnings; my $x; print $x;' Use of uninitialized value in print at -e line 5.

    I can see at a glance that the lone print statement is line 5 and, if I had a problem, I could tell the monks "Look, there's where I get the error".

    So, try reporting where the error is and we'll try to narrow it down for you (though I suspect that it lies in your SQL returning nothing).

    Update: I tried refactoring and cleaning up your code a little bit:

    $user = $dbh->quote( $user ); my ( $field, $sub_parent ) = $parent eq 'Father' ? ( 'Father', "'Mother'" ) : ( 'Mother', "'Father'" ); $sth = $dbh->prepare ("select $field from Roster where User = $user"); $sth->execute (); my $name = $sth->fetchrow_array; if ($name eq ""){ $sth = $dbh->prepare ("select $sub_parent from Roster where User = + $user"); $sth->execute (); $name = $sth->fetchrow_array; } #end chk for not parent if statement. print $query->h1({-align=>'center'},"THANK YOU FOR SIGNING UP $name"); $sth = $dbh->prepare ("select distinct Volunteer from Volunteer where +Volunteer = ? and Date = ?"); foreach my $date ( @volunteer_date ) { $sth->execute ( $name, $date ); my $chk = $sth->fetchrow_array; if ($chk eq $name) { print $query->h1({-align=>'center'}, "You are already signed u +p for this date: $date"); } #end if statement else { $sth = $dbh->prepare ("select max(Number) from Volunteer where + Date = ? and Volunteer = 'TBD'"); $sth->execute ($date );

    After doing this, I saw that you are not using strict and you have some serious scoping issues. These scoping issues make this difficult. As I see from your code below, the problem lies in $user not being initialized.

    $sth = $dbh->prepare ("select Mother from Roster where User = \'$user\ +'");

    Thus, your problem occurred before the snipped that you presented us with. Also, note in my cleanup above that I used the $dbh->quote method. This will save you much grief, rather than trying to escape the data with single quotes (if the data contains single quotes, your escaping it will fail, for example). I suggest you read the DBI documentation very carefully.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      I'm sorry about not being more specific.
      here is the code with the line numbers.
      #Selecting parents name to identify as volunteer. 35 if ($parent eq "Father") 36 { 37 $sub_parent = "Mother"; 38 $sth = $dbh->prepare ("select Father from Roster where + User = \'$user\'"); 39 $sth->execute (); 40 41 $name = $sth->fetchrow_array; 42 } #end if Father 43 else 44 { 45 $sub_parent = "Father"; 46 $sth = $dbh->prepare ("select Mother from Roster where + User = \'$user\'"); 47 $sth->execute (); 48 49 $name = $sth->fetchrow_array; 50 } #end else Mother 51 52 if ($name eq ""){ 53 $sth = $dbh->prepare ("select $sub_parent from Roster +where User = \'$user\'"); 54 $sth->execute (); 55 56 $name = $sth->fetchrow_array; 57 58 } #end chk for not parent if statement. 59 60 print $query->h1({-align=>'center'},"THANK YOU FOR SIGNING UP +$name"); 61
      I am certain it has something to do with returning an empty string from my sql as well but I don't know what that something is

        When calling $sth->fetchrow_array in a scalar context, you're going to get back an array ref, possibly containing some other array refs (your result rows). So your test, if ($name eq "") {, should probably look more like, if ($name->[0][0] eq "") {, except that this completely disregards the case where no rows are returned.

        You might also factor out all of the common code and elminate unnecessary complexity:

        my $name = undef; # store subparent for each parent my %parent_hash = ( 'Father' => 'Mother', 'Mother' => 'Father' ); if (exists $parent_hash{$parent}) { my $sub_parent = $parent_hash{$parent}; for my $col ( $parent, $sub_parent ) { my $sql = "select $col from Roster where User=?"; my $rv = $dbh->selectcol_arrayref( $sql, undef, $user ); if ( @$rv ) { # any rows returned? $name = $rv->[0]; # take first one last; } } } # here, $name will be defined if one of above succeeded # etc. ...

        Also, why are you using prepared statements (e.g., prepare() and execute()) without placeholders ('?'). You can just call selectrow_arrayref($sql) (or in your case, selectcol_arrayref($sql) since the results will be a single column) to the same effect.

        Update: added placeholders, as per cfreak. What was I thinking?

        dmm

        If you GIVE a man a fish you feed him for a day
        But,
        TEACH him to fish and you feed him for a lifetime
Re: uninitialized value in concatenation
by cfreak (Chaplain) on Jan 14, 2002 at 22:55 UTC

    Well those sound to me like warnings (do you have use warnings or a -w on your #! line?) The reason you are getting them doesn't seem to be immediatly clear. Its possible that you queries are doing because you have the variables interpolated in the string of your query.

    A much better way to do that is to use placeholders. Placeholders keep your code cleaner and easier to maintain and it also allows the DBI module to filter out dangerous characters from variables passed to the program. You create a placeholder by using a ? instead of the variable name and then putting the variable in your execute statement. Part of your code would look like this:

    if ($parent eq "Father") { $sub_parent = "Mother"; $sth = $dbh->prepare ("select Father from Roster where User = +?); $sth->execute($user) or die $sth->errstr; # putting 'or die $sth->errstr;' will tell you if # your query fails and why $name = $sth->fetchrow_array; } #end if Father

    That may or may not take care of the warnings. But even if it doesn't its a good practice.

    Hope that helps
    Chris

Re: uninitialized value in concatenation
by mrbbking (Hermit) on Jan 14, 2002 at 23:25 UTC
    In lines 46 and 53, the only variable is $user. So, it must not have a value at that point in your program.

    In lines 52 and 60, the only variable is $name. So, it must not have a value at that point in your program.

    Suggestion: Explicitly set $user and $name to some value that makes sense. (Something like $user="Bob";$name="Robert";). Do this somewhere before line 46 for $user and before line 52 for $name.

    Re-run and see what happens. My guess is that you'll get past these warnings. Earlier in your code, the program must be skipping over the lines where these variables get values.

Re: uninitialized value in concatenation
by screamingeagle (Curate) on Jan 14, 2002 at 23:58 UTC
    My suggestion would be to use HERE documents (or at least simple scalar variables containing the SQL statements and using those variables in the dbh->prepare statements. The code would look cleaner and be easier to debug. For e.g. :
    $sql = "select $sub_parent from Roster where User = '" . $user . "'"; $sth = $dbh->prepare ($sql); $sth->execute ();