This is a code tweaking question; a question to improve my coding skills. One of my web site runs almost totally on Perl CGI and DBI scripts. All data for the site is stored in MySQL. For each web page generated, I want to include meta-keywords for the search engines to use. These keywords are stored in a table in MySQL. For each CGI script, I call a subroutine located in a library file which queries the meta-keywords table for the keywords for a given script and its parameters. I need those keywords to be returned in a comma-separated list and in a string.
Here's an example of the line of code in the calling CGI script:
my $meta_keywords = &get_meta_keywords($script,$parameter);Below is the code for the called subroutine:
sub get_meta_keywords { my ($script,$parameter) = @_; $sql_stmnt = "SELECT meta_keyword FROM site_meta_keywords WHERE script = ? AND parameter = ?"; $sth = $dbh->prepare($sql_stmnt); $sth->execute($script,$parameter); my $keywords = $sth->fetchall_arrayref(); $sth->finish(); my $meta_keywords = join(', ', @$keywords); return $meta_keywords; }
This returns the correct number of elements, separated by commas, but each element is an array and not text. I realize that this is part of the nature of the fetchall_arrayref() from DBI. However, I should think that there is a way I can dereference this, properly. For some background understanding, I created this simple script to test my use of join with a referenced array:
#!/usr/bin/perl -w my @keywords = qw(one two three); my $keywords = \@keywords; my $meta_keywords = join(',', @$keywords); print $meta_keywords, "\n"; exit;
The code above returns the following text:
one,two,threeThe difference, of course and again, is that fetchall_arrayref() returns not only a reference to an array, but the array it references is an array of arrays. Meaning, although I'm only selecting one column in MySQL, I could as easily select multiple columns and thereby each element of the array that's referenced contains an array of all of the columns I select. In this case only one element is contained in each sub-array.
A simple solution to my problem would be to do the following:
sub get_meta_keywords { ... my @keywords; while(my ($keyword) = $sth->fetchrow_array()) { push(@keywords, $keyword); } $sth->finish(); my $meta_keywords = join(', ', @keywords); return $meta_keywords; }
This works just fine. If you've read this far, you may be wondering what is my question and what is my problem. It seems to me that I should be able to retrieve the whole array in one line and then dereference the array to the level I need, and not have to resort to a while statement. I know it's not that much extra code, but it seems amateurish and I'm trying to improve my coding skills. So, if you know a way to tighten up this code, please let me know. It seems like I should be able to do something like, $@keywords->[0] (which doesn't work either) inside the join. Please let me know if there is a way to do this or if there isn't anything better than using a while as I've done, so that I can give up. Thanks.
-Spenser
That's Spenser, with an "s" like the detective.
In reply to join and fetchall_arrayref() by Spenser
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |