Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Can't use an undefined value as an ARRAY reference at search.cgi line 139. (http://www.velocityreviews.com/forums/t904562-cant-use-an-undefined-value-as-an-array-reference-at-search-cgi-line-139-a.html)

JimJx 09-11-2007 06:15 PM

Can't use an undefined value as an ARRAY reference at search.cgi line 139.
 
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


J. Gleixner 09-11-2007 07:05 PM

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.

Paul Lalli 09-11-2007 07:09 PM

Re: Can't use an undefined value as an ARRAY reference at search.cgi line 139.
 
On Sep 11, 2:15 pm, JimJx <webmas...@valleywebnet.com> 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


John W. Krahn 09-11-2007 09:37 PM

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

JimJx 09-12-2007 12:14 PM

Re: Can't use an undefined value as an ARRAY reference at search.cgi line 139.
 
On Sep 11, 5:37 pm, "John W. Krahn" <du...@example.com> 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


Paul Lalli 09-12-2007 02:10 PM

Re: Can't use an undefined value as an ARRAY reference at search.cgi line 139.
 
On Sep 11, 5:37 pm, "John W. Krahn" <du...@example.com> 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


John W. Krahn 09-12-2007 04:10 PM

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" <du...@example.com> 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


All times are GMT. The time now is 05:08 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.