Can't use an undefined value as an ARRAY reference at search.cgi line 139.

Discussion in 'Perl Misc' started by JimJx, Sep 11, 2007.

  1. JimJx

    JimJx Guest

    Hi all,

    I have what seems to me to be a strange problem....

    I have the script below:

    <code>
    if ($type eq 'alpha') {
    $query = sprintf (
    "SELECT name, address, city, phone
    FROM valley
    where name like '$search%'
    ORDER BY name LIMIT %d,%d",
    $start - 1, # number of records to skip
    $per_page + 1); # number of records to select
    } elsif ($type eq '') {
    $query = sprintf (
    "SELECT name, address, city, phone
    FROM valley
    where keywords like '%$search%'
    ORDER BY name LIMIT %d,%d",
    $start - 1, # number of records to skip
    $per_page + 1); # number of records to select
    }
    my $tbl_ref = $dbh->selectall_arrayref ($query);

    $dbh->disconnect ( );

    # Display results as HTML table

    for (my $i = 0; $i < $per_page && $i < @{$tbl_ref}-1; $i+=2) {
    # get data values in row $i
    my @cells = @{$tbl_ref->[$i]}; # get data values in row $i
    my @cells2 = @{$tbl_ref->[$i+1]}; # get data values in row $i+1
    # map values to HTML-encoded values, or to &nbsp; if null/empty
    @cells = map {
    defined ($_) && $_ ne "" ? escapeHTML ($_) : "&nbsp;"
    } @cells;
    @cells2 = map {
    defined ($_) && $_ ne "" ? escapeHTML ($_) : "&nbsp;"
    } @cells2;
    # add cells to table
    my @cells = "<b>$cells[0]</b><br>$cells[1]<br>$cells[2]<br>
    $cells[3]<br>";
    my @cells2 = "<b>$cells2[0]</b><br>$cells2[1]<br>$cells2[2]<br>
    $cells2[3]<br>";
    push (@rows, Tr (td (\@cells),(td (\@cells2))));
    }
    </code>

    It works great. However if I change it to:
    <code>
    if ($search = '#') {
    $query = sprintf (
    "SELECT name, address, city, phone
    FROM valley where REGEXP '^[0-9]'
    ORDER BY name LIMIT %d,%d",
    $start - 1,
    $per_page + 1);
    } elsif ($type eq 'alpha') {
    $query = sprintf (
    "SELECT name, address, city, phone
    FROM valley
    where name like '$search%'
    ORDER BY name LIMIT %d,%d",
    $start - 1, # number of records to skip
    $per_page + 1); # number of records to select
    } elsif ($type eq '') {
    $query = sprintf (
    "SELECT name, address, city, phone
    FROM valley
    where keywords like '%$search%'
    ORDER BY name LIMIT %d,%d",
    $start - 1, # number of records to skip
    $per_page + 1); # number of records to select
    }
    my $tbl_ref = $dbh->selectall_arrayref ($query);

    $dbh->disconnect ( );

    # Line 139 is the FOR below......

    for (my $i = 0; $i < $per_page && $i < @{$tbl_ref}-1; $i+=2) {
    # get data values in row $i
    my @cells = @{$tbl_ref->[$i]}; # get data values in row $i
    my @cells2 = @{$tbl_ref->[$i+1]}; # get data values in row $i+1
    # map values to HTML-encoded values, or to &nbsp; if null/empty
    @cells = map {
    defined ($_) && $_ ne "" ? escapeHTML ($_) : "&nbsp;"
    } @cells;
    @cells2 = map {
    defined ($_) && $_ ne "" ? escapeHTML ($_) : "&nbsp;"
    } @cells2;
    # add cells to table
    my @cells = "<b>$cells[0]</b><br>$cells[1]<br>$cells[2]<br>
    $cells[3]<br>";
    my @cells2 = "<b>$cells2[0]</b><br>$cells2[1]<br>$cells2[2]<br>
    $cells2[3]<br>";
    push (@rows, Tr (td (\@cells),(td (\@cells2))));
    }
    </code>
    I get the error 'Can't use an undefined value as an ARRAY reference at
    search.cgi line 139.'

    My questions, why would adding that code at the beginning cause that
    error and how can I fix it?

    Any ideas/suggestions greatly appreciated.
    Jim
    JimJx, Sep 11, 2007
    #1
    1. Advertising

  2. JimJx

    J. Gleixner Guest

    Re: Can't use an undefined value as an ARRAY reference at search.cgiline 139.

    JimJx wrote:
    > Hi all,
    >
    > I have what seems to me to be a strange problem....
    >
    > I have the script below:


    Which isn't terribly helpful, because you don't say what $type,
    $start, etc. is so we have no idea what SQL is being tried.
    [...]
    > My questions, why would adding that code at the beginning cause that
    > error and how can I fix it?
    >
    > Any ideas/suggestions greatly appreciated.


    Look at your SQL and the results.

    use Data::Dumper;

    #... your code
    print "SQL=$query\n";
    my $tbl_ref = $dbh->selectall_arrayref ($query);
    print 'Results:', Dumper( $tbl_ref );

    Something isn't what you think it is.
    J. Gleixner, Sep 11, 2007
    #2
    1. Advertising

  3. JimJx

    Paul Lalli Guest

    On Sep 11, 2:15 pm, JimJx <> wrote:

    > It works great. However if I change it to:
    > <code>
    > if ($search = '#') {


    You realize of course that this line *assigns* $search to be equal to
    '#', and then returns true, meaning that this if statement (and none
    of the else clauses) will ALWAYS be executed, right?

    You meant to have an 'eq' here, just like all the other if conditions
    had, not an '='.

    > my $tbl_ref = $dbh->selectall_arrayref ($query);
    >
    > $dbh->disconnect ( );
    >
    > # Line 139 is the FOR below......
    >
    > for (my $i = 0; $i < $per_page && $i < @{$tbl_ref}-1; $i+=2) {


    > I get the error 'Can't use an undefined value as an ARRAY
    > reference at search.cgi line 139.'


    You are not checking your DBI calls for errors. You are assuming they
    all work fine. Perl doesn't tell you there's a problem unless you ask
    it to. I recommend turning on RaiseError in your connect statement

    my $dbh = DBI->connect($dsn, $user, $pass, { RaiseError => 1} );

    Or you can turn it on after the fact:
    $dbh->{RaiseError} = 1;

    Or you can manually check the results of every single database call:
    my $tbl_ref = $dbh->selectall_arrayref($query);
    die $dbh->errstr if $dbh->err();


    Paul Lalli
    Paul Lalli, Sep 11, 2007
    #3
  4. Re: Can't use an undefined value as an ARRAY reference at search.cgiline 139.

    JimJx wrote:
    >
    > I have what seems to me to be a strange problem....
    >
    > I have the script below:
    >
    > <code>
    > if ($type eq 'alpha') {
    > $query = sprintf (
    > "SELECT name, address, city, phone
    > FROM valley
    > where name like '$search%'
    > ORDER BY name LIMIT %d,%d",
    > $start - 1, # number of records to skip
    > $per_page + 1); # number of records to select
    > } elsif ($type eq '') {
    > $query = sprintf (
    > "SELECT name, address, city, phone
    > FROM valley
    > where keywords like '%$search%'
    > ORDER BY name LIMIT %d,%d",
    > $start - 1, # number of records to skip
    > $per_page + 1); # number of records to select
    > }
    > my $tbl_ref = $dbh->selectall_arrayref ($query);
    >
    > [ SNIP ]
    >
    > </code>
    >
    > It works great.


    Are you sure that that "works great"?

    You have variable interpolation inside sprintf() format strings and you are
    using '%' without properly escaping it. You probably want this instead:

    if ( $type eq 'alpha' ) {
    $query = sprintf
    "SELECT name, address, city, phone
    FROM valley
    where name like '%s%%'
    ORDER BY name LIMIT %d,%d",
    $search,
    $start - 1, # number of records to skip
    $per_page + 1; # number of records to select
    } elsif ( $type eq '' ) {
    $query = sprintf
    "SELECT name, address, city, phone
    FROM valley
    where keywords like '%%%s%%'
    ORDER BY name LIMIT %d,%d",
    $search,
    $start - 1, # number of records to skip
    $per_page + 1; # number of records to select
    }
    my $tbl_ref = $dbh->selectall_arrayref( $query );



    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
    John W. Krahn, Sep 11, 2007
    #4
  5. JimJx

    JimJx Guest

    On Sep 11, 5:37 pm, "John W. Krahn" <> wrote:
    > JimJx wrote:
    >
    > > I have what seems to me to be a strange problem....

    >
    > > I have the script below:

    >
    > > <code>
    > > if ($type eq 'alpha') {
    > > $query = sprintf (
    > > "SELECT name, address, city, phone
    > > FROM valley
    > > where name like '$search%'
    > > ORDER BY name LIMIT %d,%d",
    > > $start - 1, # number of records to skip
    > > $per_page + 1); # number of records to select
    > > } elsif ($type eq '') {
    > > $query = sprintf (
    > > "SELECT name, address, city, phone
    > > FROM valley
    > > where keywords like '%$search%'
    > > ORDER BY name LIMIT %d,%d",
    > > $start - 1, # number of records to skip
    > > $per_page + 1); # number of records to select
    > > }
    > > my $tbl_ref = $dbh->selectall_arrayref ($query);

    >
    > > [ SNIP ]

    >
    > > </code>

    >
    > > It works great.

    >
    > Are you sure that that "works great"?
    >
    > You have variable interpolation inside sprintf() format strings and you are
    > using '%' without properly escaping it. You probably want this instead:
    >
    > if ( $type eq 'alpha' ) {
    > $query = sprintf
    > "SELECT name, address, city, phone
    > FROM valley
    > where name like '%s%%'
    > ORDER BY name LIMIT %d,%d",
    > $search,
    > $start - 1, # number of records to skip
    > $per_page + 1; # number of records to select
    > } elsif ( $type eq '' ) {
    > $query = sprintf
    > "SELECT name, address, city, phone
    > FROM valley
    > where keywords like '%%%s%%'
    > ORDER BY name LIMIT %d,%d",
    > $search,
    > $start - 1, # number of records to skip
    > $per_page + 1; # number of records to select}
    >
    > my $tbl_ref = $dbh->selectall_arrayref( $query );
    >
    > John
    > --
    > Perl isn't a toolbox, but a small machine shop where you
    > can special-order certain sorts of tools at low cost and
    > in short order. -- Larry Wall


    John, the %$search and %$search% that I think you are referring to are
    correct in this case. The $search% means match anything with the
    search term at the beginning, and similarly, the %$search% means match
    if the term is found anywhere.....

    Paul, good catch on the eq, guess that is what happens after looking
    at code for so long, it all starts to look the same.... I turned on
    the error checking and did not get any errors there so the eq was it.

    Thanks guys for taking the time to help me out, I really appreciate
    it.

    Jim
    JimJx, Sep 12, 2007
    #5
  6. JimJx

    Paul Lalli Guest

    On Sep 11, 5:37 pm, "John W. Krahn" <> wrote:
    > JimJx wrote:
    >
    > > I have what seems to me to be a strange problem....

    >
    > > I have the script below:

    >
    > > <code>
    > > if ($type eq 'alpha') {
    > > $query = sprintf (
    > > "SELECT name, address, city, phone
    > > FROM valley
    > > where name like '$search%'
    > > ORDER BY name LIMIT %d,%d",
    > > $start - 1, # number of records to skip
    > > $per_page + 1); # number of records to select
    > > } elsif ($type eq '') {
    > > $query = sprintf (
    > > "SELECT name, address, city, phone
    > > FROM valley
    > > where keywords like '%$search%'
    > > ORDER BY name LIMIT %d,%d",
    > > $start - 1, # number of records to skip
    > > $per_page + 1); # number of records to select
    > > }
    > > my $tbl_ref = $dbh->selectall_arrayref ($query);

    >
    > > [ SNIP ]

    >
    > > </code>

    >
    > > It works great.

    >
    > Are you sure that that "works great"?
    >
    > You have variable interpolation inside sprintf() format strings


    Nothing about Perl prevents that. There's no reason to think that
    wouldn't "work great"

    > and you are using '%' without properly escaping it.


    Yes, but if the character following the % isn't a valid format
    specifier, it prints out as a % literal anyway:

    printf "%d, %'\n", 5; #prints 5, %'

    In short, there's nothing "wrong" with that part of the OP's code. It
    could be made to look better, as you suggest, but there's nothing
    about it that suggests it doesn't work.

    Paul Lalli
    Paul Lalli, Sep 12, 2007
    #6
  7. Re: Can't use an undefined value as an ARRAY reference at search.cgiline 139.

    Paul Lalli wrote:
    > On Sep 11, 5:37 pm, "John W. Krahn" <> wrote:
    >> JimJx wrote:
    >>
    >>> I have what seems to me to be a strange problem....
    >>> I have the script below:
    >>> <code>
    >>> if ($type eq 'alpha') {
    >>> $query = sprintf (
    >>> "SELECT name, address, city, phone
    >>> FROM valley
    >>> where name like '$search%'
    >>> ORDER BY name LIMIT %d,%d",
    >>> $start - 1, # number of records to skip
    >>> $per_page + 1); # number of records to select
    >>> } elsif ($type eq '') {
    >>> $query = sprintf (
    >>> "SELECT name, address, city, phone
    >>> FROM valley
    >>> where keywords like '%$search%'
    >>> ORDER BY name LIMIT %d,%d",
    >>> $start - 1, # number of records to skip
    >>> $per_page + 1); # number of records to select
    >>> }
    >>> my $tbl_ref = $dbh->selectall_arrayref ($query);
    >>> [ SNIP ]
    >>> </code>
    >>> It works great.

    >> Are you sure that that "works great"?
    >>
    >> You have variable interpolation inside sprintf() format strings

    >
    > Nothing about Perl prevents that. There's no reason to think that
    > wouldn't "work great"
    >
    >> and you are using '%' without properly escaping it.

    >
    > Yes, but if the character following the % isn't a valid format
    > specifier, it prints out as a % literal anyway:
    >
    > printf "%d, %'\n", 5; #prints 5, %'


    And a warning message:

    $ perl -Mwarnings -Mstrict -e "my \$x = q[aa]; printf qq[variable '%\$x%' five
    %d seven %d\n], 5, 7"
    Invalid conversion in printf: "%a" at -e line 1.
    Invalid conversion in printf: "%'" at -e line 1.
    variable '%aa%' five 5 seven 7


    And if it is valid then you get uninitialized values at the end of the list:

    $ perl -Mwarnings -Mstrict -e "my \$x = q[dd]; printf qq[variable '%\$x%' five
    %d seven %d\n], 5, 7"
    Invalid conversion in printf: "%'" at -e line 1.
    Use of uninitialized value in printf at -e line 1.
    variable '5d%' five 7 seven 0


    > In short, there's nothing "wrong" with that part of the OP's code. It
    > could be made to look better, as you suggest, but there's nothing
    > about it that suggests it doesn't work.




    John
    --
    Perl isn't a toolbox, but a small machine shop where you
    can special-order certain sorts of tools at low cost and
    in short order. -- Larry Wall
    John W. Krahn, Sep 12, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ruby Quiz

    [QUIZ] IP to Country (#139)

    Ruby Quiz, Sep 14, 2007, in forum: Ruby
    Replies:
    37
    Views:
    334
    Simon Kröger
    Sep 19, 2007
  2. Ruby Quiz

    [SUMMARY] IP to Country (#139)

    Ruby Quiz, Sep 20, 2007, in forum: Ruby
    Replies:
    0
    Views:
    148
    Ruby Quiz
    Sep 20, 2007
  3. Replies:
    4
    Views:
    238
  4. Replies:
    2
    Views:
    240
    Gunnar Hjalmarsson
    Feb 26, 2006
  5. Replies:
    0
    Views:
    129
Loading...

Share This Page