fetchrow_hashref issue in perl - mysql

I am not able to retrieve the output properly using the below code. Please help me to sort it out.
I am getting output differently to run in MySQL and Perl.
As of now it is returning undef when I use Dumper. But I want it to display null.
$reactivate_sth = $dbh->prepare("
SELECT
a,
b
FROM
table
WHERE
c = ?
AND
d = ?
ORDER BY
date DESC
");
$reactivate_sth->execute($c, $d);
print $result = $reactivate_sth->fetchrow_hashref();
OUTPUT:
MySQL:
Empty set (0.00 sec)
Perl:
HASH(0x3068198)
Data::Dumper
VAR1 = undef

You must make your code more readable. It's often useful to use a heredoc to quote SQL statements, like this
my $reactivate_sth = $dbh->prepare(<<END_SQL);
SELECT a, b
FROM table
WHERE c = ? AND d = ?
ORDER BY date DESC
END_SQL
$reactivate_sth->execute($c, $d);
my $result = $reactivate_sth->fetchrow_hashref;
Now $result is a reference to a hash, because you called the fetchrow_hashref method. Printing it will, as you have found, produce something like HASH(0x1cc5a8). You need to access the elements of the hash to make sense of the result
After that, I don't know what output you want. You can use the core Data::Dumper module to display the record that you've retrieved like this
use Data::Dumper;
print Dumper $result;
Does that help? You haven't asked for anything more

Finally I found the solution for this issue. I am not sure this one is a proper fix or not.
Please guide me if the fix is not professional.
if (!defined $result->{''}) {
$result = '';
}

Related

Symfony Query in controller

$query = $em->query("
SELECT c.id AS id
FROM collectif c, zone z
WHERE
c.zone_id = z.id
AND z.label = '$zone'
ANDc.collectif = '$collectif'
");
$c = $query->fetchAll();
$idc = $c['id'];
I have this query that returns a single line, Symfony shows me an error as what variable id undefined
NB: I know that's don't respect the concept of Symfony [MVC] but it's for a particular reason so if someone can tell me how I can resolve this problem
Thank you
$query->fetchAll() should return numeric array of elements so key id does not exists. You should try $c[0]['id'] to get value.
If you'd rather use the results in the assocative way, you can use fetchAssoc() instead:
$c = $query->fetchAssoc();
$idc = $c['id'];
Here is the documentation for reference:
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/data-retrieval-and-manipulation.html#fetchassoc
I'm just giving an alternate way to do this.

Simple perl mysql query not working

I've been out of the mysql and perl game for quite a few years and can't seem to get this right. I have a table with just 3 columns. 'cnt' is one of them. All I want to do is query the table on 'name' and see if name exists. If it does, I want to capture the value of 'cnt'. The table has a record of testName with a value of 2 I added manually. When this script is run it returns empty.
my $count;
my $pop = qq(SELECT cnt FROM popular WHERE name="testName");
my $sth = $dbh->prepare($pop);
$sth->execute() or die $dbh->errstr;
my #return;
while (#return = $sth->fetchrow_array()) {
$count = $return[1];
}
print "our return count is $count";
Is it obvious to anyone what I did wrong?
You probably mean
$count = $return[0];
According to perl doc on mysql
An alternative to fetchrow_arrayref. Fetches the next row of data and returns it as a list containing the field values.
Since you select cnt as the return value ,so , the size of #return is 1,but you misunderstand it as the number of results which meets your query condition.No, it is not so!Please have a more careful reading of perl doc.

Getting the max row character length in a query using Perl DBI Mysql

Using: Perl v5.10.1, MySQL 5.5.15, DBI.
I need to deliver end users output from a database via email. They do not want this as an attachment, but in the body.
I'd like to deliver the data in an ascii table and am having issues determining if DBI has built in functions to do this (output similar to querying MySQL from the command line).
Or If I can determine the longest row character length I can use that to build the table. I have a way to get the max item length in an array, but I can't wrap my head around doing it with the query results.
my $spacer_length = (reverse sort { $a <=> $b } map { length($_) } #array)[0];
Assuming a generic DBI loop, you could do something like this:
use List::Util qw(max);
...
my #output;
my $max;
while (my #foo = $dbi->fetchrow_array) {
$max = max($max // (), map length, #foo);
push #output, \#foo; # save data for email attachment
}
Using the "defined-or" operator // to avoid an undef warning and possible contamination in case of negative values.
I'm not sure exactly what you're asking for, but if you're looking for the "max row character length" for a given column of a query result, you can do that with SQL:
SELECT MAX(CHAR_LENGTH(col1)) FROM t1
or if you want all of the rows sorted by the length of the values of col1:
SELECT col1,col2 from t1 ORDER BY CHAR_LENGTH(col1) DESC
you can execute these queries using DBI like this:
# $mysql is your DBI connection info
my $query = $mysql->prepare("SELECT col1,col2 from t1 ORDER BY CHAR_LENGTH(col1) DESC");
$query->execute();
and then iterate through the result rows:
while ( my #result = $query->fetchrow_array ) {
my ($col1,$col2) = #result;
# do stuff with the values
}
and you can print the values as you wish, including like the output from the command line mysql client.

number of parameters requested in a select statement

This is probably a somewhat simple question but I am trying to make sure that a query statement (specifically a select statement) contains a specific number of parameters only:
$result = mysql_query("select type,some_other_column from my_table");
$row = mysql_fetch_array($result);
$number = count($row);
print $number;
This returns twice the number I think it should return (4) - as I believe it must also be returning the key and the value as separate parameters.
The select statement above is just an example and it could be any number of statements. They could be a lot more complicated and the tests I have run do not seem to have any problems. I want to make sure that there are only ever two parameters (it can be any two) and they could be from different tables too.
I just want to make sure that it that what I am doing above is both the fastest way to check that the number of parameters is correct and that it won't get upset if there is a much more complicated statement given to it.
I am sure there is a really easy answer to this. Thanks in advance for any help.
Try mysql_fetch_assoc or mysql_fetch_row. Both functions available on php.net
mysql_fetch_array -- Fetch a result row as an associative array, a numeric array, or both. You end up having
$row["type"] = "somevalue"; // AND
$row[0] = "somevalue";
hence double the number
Whatever you SELECT would be in the $row variable, so in your code:
$result = mysql_query("select type,some_other_column from my_table");
$row = mysql_fetch_array($result);
/*
$row = array(
'type' => 'type_value',
'0' => 'type_value',
'some_other_column' => 'col_value',
'1' => 'col_value'
)
*/
$number = count($row);
print $number; // prints 4
I am not sure i understood your question right.
Do you just want to limit your number of returned values to one row?
If this is your point, you can add LIMIT 1 to your SQL-Query. This would, as it says, limit the number of results to one row.

MySQL - Perl: How to use an array with IN within a select query? (WHERE IN (#array))

This is an addition to my solved question here:
how to get array of zip codes within x miles in perl
OK, I have the array #zips. Now I am trying to use it in a query like this:
SELECT `club_name`,`city` FROM `table` WHERE `public_gig` = 'y' AND `zip` IN (#zips)
#I also tried syntax "IN ("#zips"), IN #zips and IN ('#zips')"
But, I cannot get it to work. (I am using placeholders and such as you see in my link above.)
I was able to get this to work:
$fzip=shift(#Zips);
$lzip=pop(#Zips);
SELECT `club_name`,`city` FROM `table` WHERE `public_gig` = 'y' AND `zip` BETWEEN $fzip AND $lzip
ZIP | public_gig | start_time | fin_time | city | club_name | and so on
33416 | y | 9pm | 2am | clearwater | beach bar | yada
But, for obvious reasons and some resemblance of accuracy, that is not really what I want. Just wanted to see if I could get SOMETHING working on my own.
Why can't I get the query to work with the zips in the array using IN?? Nothing is returned and there is no error.
There is actually a lot more in that query but, I left it all out to keep it short here.
I tried to figure it out by myself. Obviously, my learning capacity for the day is near peak.
Thanks for any help.
All of the examples posted here will screw up if any of your values contain single-quotes, don't use them.
Instead (assuming $dbh is the database handle for your mysql connection):
my $zip_string = join q{,}, map $dbh->quote($_), #zips;
and interpolate that.
Or, for something nice, but not half as outlandish as DBIx::Perlish: SQL::Abstract.
my $sqla = SQL::Abstract->new;
my ($sql, #bind) = $sqla->select(
'table',
['club_name', 'city'],
{
public_gig => y',
zip => { -in => \#zips },
}
);
$dbh->prepare($sql);
$dbh->execute(#bind);
# fetchrow etc.
This can be done using placeholders, you just have to work around the limitation that each placeholder can only accept a single value. WHERE zip IN (?) won't work because you're (presumably) looking for more than one value (otherwise, why use IN?).
You can, however, easily build a statement on the fly with the correct number of placeholders:
#!/usr/bin/env perl
use strict;
use warnings;
my #zips = (12345, 54321, 90210);
my $stmt = "SELECT `club_name`,`city`
FROM `table`
WHERE `public_gig` = 'y' AND `zip` IN ("
. join(', ', ('?') x #zips) . ')';
print "$stmt\n";
# Now just:
# my $sth = $dbh->prepare($stmt);
# $sth->execute(#zips);
Alternatively, if you don't mind using weird CPAN modules,
with DBIx::Perlish you can just say:
my #results = db_fetch {
my $t: table;
$t->public_gig eq "y";
$t->zip <- #zips;
};
and it will do the right thing.
Full disclosure: I am the author of DBIx::Perlish.
I don't know perl too much, but this looks like a simple SQL problem: why don't you just build the SQL IN clause from your array? You should get something like
AND zip IN ('zip 1', 'zip 2', '...')
I doubt just adding an array in perl will create the right strings for the SQL string ...
You need to turn the array into a string of values seperated by commas.
Try this :
my $zipcodes = join('\',\'',#zips);
SELECT `club_name`,`city` FROM `table` WHERE `public_gig` = 'y' AND `zip` IN ('".$zipcodes."');