mysql , perl script freezing when retrieving data - mysql

Hi I have this code. my perl scripts hangs somewhere in the #row section. I printed the next query statement and it works in SQL.
Why is it hanging?
foreach $device (...)
$sth2 = $dbh->prepare(qq|SELECT DISTINCT S,`W(m)`,`L(m)`,V FROM `$SQL_TABLE_NAME` WHERE DEVICE='$device'| );
$sth2->execute( );
my %TEMP = ();
while ( my #row = $sth2->fetchrow_array( ))
{
$TEMP{S}{$row[0]} = 1;
$TEMP{W}{$row[1]} = 1;
$TEMP{L}{$row[2]} = 1;
$TEMP{V}{$row[3]} = 1;
}

You seem to have a syntax error in your query (VFROM rather than V FROM).
If the query fails, there's no result set to fetch a row from. You might want to build some error handling into your code.

my $select_line = qq|SELECT DISTINCT S,`W(m)`,`L(m)`,V
FROM `$SQL_TABLE_NAME`
WHERE DEVICE='$device'|;
Have you tried printing the $select_line and then running it directly in mysql?
my $sth2 = $dbh->prepare( $select_line )
or die $DBI::errstr.' at my query: $select_line\n';
Add in or die $DBI::errstr.' at my query: $select_line' to verify if your syntax is correct.
Add in die $sth2->errstr if $sth2->err; after your while:
while (fetch) {
//stuff in here with rows
} die $sth2->errstr if $sth2->err;
Review CPAN DBI docs # http://metacpan.org/pod/DBI

By the way it's better to use placeholders:
$sth2 = $dbh->prepare(qq|SELECT DISTINCT S,`W(m)`,`L(m)`,V FROM `$SQL_TABLE_NAME` WHERE DEVICE= ?| );
$sth2->execute($device);

Related

how to display count() sql function using php

how to display count() sql function using php
$results = "SELECT count(votesnumber) FROM `votes` WHERE `candidate_id` = '$candidate_id'";
$queryresults = mysqli_query($connect, $results);
if($queryresults) {
$rowresults = mysqli_fetch_assoc($queryresults);
echo $rowresults['votesnumber'];
} else {
echo "error";
}
i want to display the results of sql count() function using php. am counting specific columns WHERE ID = "some value" in phpmyadmin its working but with php its giving me headache . any ideas on how to solve this?
Try this:
$results = "SELECT count(votesnumber) AS VoteNum FROM `votes` WHERE `candidate_id` = '$candidate_id'";
$queryresults = mysqli_query($connect, $results);
if($queryresults) {
$rowresults = mysqli_fetch_assoc($queryresults);
echo $rowresults['VoteNum'];
} else {
echo "error";
}
First, if you want to refer to the column name by a reference, then you need to give it a better name using an alias:
SELECT COUNT(votesnumber) as votesnumber
ROM `votes`
WHERE `candidate_id` = '$candidate_id';
Second, you should not be munging query strings with parameter values. Instead of '$candidate_id', learn to use parameters. This prevents unexpected syntax errors and SQL injection accounts.
Third, if votesnumber is actually a number of votes, then you probably want SUM() rather than COUNT().
You need to add "AS" instruction to your SQL if you want to get this data as a specific index from array (like $rowresults['votes']):
$results = "SELECT count(votesnumber) AS votes FROM `votes` WHERE `candidate_id` = '$candidate_id'";
Remember that you can always print_r() (for arrays) or var_dump() your variable to check if it contains data you want to have.

Select or Return "field" names from a query (not table) in MySQL

I have a Dynamic Pivot in MySQL (see this question: MySQL "Multi-Dimensional?" Dynamic Pivot)
I want to know the Column/As/Field names as if it were a table and I queried INFORMATION_SCHEMA (which if this was a REAL table, would be easy enough: MySQL query to get column names?).
But, I can find no question or reference to a function or SELECT option to get the Column/As/Field names from a query. Is this possible? If so, how?
Using Perl to access MySQL (http://dbi.perl.org/).
So, flipping this around... we know the fixed columns. So, if we use the same basic query that creates the Pivot to begin with, we can get a GROUP_CONCAT of the names.
SET #sql = NULL;
SELECT GROUP_CONCAT(qrv.req_name) INTO #sql
FROM (SELECT qrt.req_name FROM qual_requirment_values qrv JOIN qual_requirment_types qrt ON qrt.id = qrv.req_type_id) qrv;
SET #sql = CONCAT('r.rank,r.member_type,im.name,qrv.grouping,', #sql);
SELECT #sql;
This can then be split into an array and used.
Seems like the long way around, but in the absence of something else it will work for my application. Seems horribly inefficient! :)
The better answer, thanks to #OllieJones. The Data Base Interface used to access MySQL should provide a way.
In my case (Perl), the answer is here: http://www.perlmonks.org/?node_id=264623
my $sql = ... [some query];
my $sth = $dbh->prepare($sql);
$sth->execute();
my $field_name_arrayref = $sth->{NAME};
Further to the answer, this is the full method within my MySQL package. do() is our generic DBI method that returns queries in an AoA. Adapting that method to create do_fieldNames();
## Tested Method
sub do_fieldNames {
my ($self, $sql, $has_results) = #_;
my ($sth, $rv, #row, #query_results);
## Execute the SQL statement
$sth = $$self->prepare($sql);
$rv = $sth->execute or &error(3306, __LINE__, __FILE__, $sql, $$self->errstr);
return undef unless $rv > 0;
## SOLUTION >> Field Name arrayref, part of the standard included DBI Perl Module
my $field_name_arrayref = $sth->{NAME};
## Parse the results
if ($has_results || $sql =~ /^select/i) {
while (#row = $sth->fetchrow_array) {
push #query_results, [ #row ];
}
}
## Return results
return (\#query_results, $field_name_arrayref) ;
}

Issue with cakePHP running unit tests

I've have the weirdest issue while trying to test something in my cakePHP 2.0 app. I have a function inside a model that queries the database to check if the app has already sent a notification in the last 25 days:
public function checkIfNotified($userId){
$query = 'SELECT count(`user_id`) AS notify '.
'FROM `churn_stats` '.
'WHERE `user_id` = '. $userId.' '.
'AND `notified` = 1 '.
'AND TIME_TO_SEC(TIMEDIFF(NOW(),`created`)) <= 2160000 ';
$this->log($query);
$result = $this->query($query);
return $result;
}
I'm doing some Unit tests to check if the method works, so I'm creating a record and trying to test it return return true like so:
$data['notified'] = 1;
$data['user_id'] = $userId;
$this->ChurnStats->create();
$this->ChurnStats->save($data);
$notified = $this->ChurnStats->checkIfNotified($userId);
print_r($notified);
After the result is (which is the wrong result since I've already inserted a row!):
Array
(
[0] => Array
(
[0] => Array
(
[notify] => 0
)
)
)
However I run the exact query generated by the code in the DB and the result is:
I've already lost a lot of time and I don't have any idea what's wrong :(.
After testing and checking everything it was another test function that somehow was changing the DB or the query of the next test, however the weird part was that the other test called the same query but didn't have any insert, update or delete that could modify the results or enviroment of the next test.
After checking everything it all reduced to something: Query Cache, by default CakePHP caches all the $this->query("..."); calls so the fix was quite easy: Deactivate it!
$result = $this->query($query, false);

Perl fetch without execute error - at end of execution

My current perl code is running through all of the rows of the database query and then throwing a
DBD::mysql::st fetchrow_hashref failed: fetch() without execute() at ./recieveTxn.cgi
line 168.
At the end. It almost is like there's something that's not telling the loop to stop at the end of the rows, but I have written it just as the others.
So for example: The query would pull up
shortcode1
shortcode2
shortcode3
then throw the error here
$sql = "
SELECT
aPI.folder AS aPIfolder,
aPI.rowNum AS aPIrowNum,
hasInput,
evalCode
FROM
aPersonalItems as aPI
LEFT JOIN
pItems_special_inputs as SI
ON
aPI.folder = SI.folder AND
aPI.rowNum = SI.rowNum
WHERE
hasInput=1 AND
aPI.folder='$FORM{'folder'}'
ORDER BY
aPI.rowNum
";
$sth = $dbh->prepare( $sql );
$sth->execute();
my ($shortcoderow, $row);
my $shortcodeSQL = "
SELECT
*
FROM
pItemsShortCodes
WHERE
folder='$FORM{'folder'}'
ORDER BY
rowNum
";
my $shortcodeSTH = $dbh->prepare( $shortcodeSQL );
$shortcodeSTH->execute();
while( my $ref = $sth->fetchrow_hashref() ) {
my $shortCode;
my $isblank = 1;
my $rowNum = $ref->{'aPIrowNum'};
while(my $shortcodeRef = $shortcodeSTH->fetchrow_hashref())
#&& $rowNum == $shortcodeRef->{'rowNum'}) #line 168 above
{
$shortCode=$shortcodeRef->{'shortcode'};
print $shortCode."\n";
}
$shortcodeSTH->finish();
}
The problem is that you are processing more than one row from $sth.
Your code fetches a row from $sth, and then your code loops through every row from $shortcodeSTH, until there are no more rows. Then your code calls the finish() method on $shortcodeSTH. (Which is the normative pattern, since you've already fetched all the rows.)
Then, your code starts through the outer loop a second time, fetching a second row from $sth. When your code attempts to start through the $shortcodeSTH loop a second time, you've already fetched all of the rows and closed the statement handle. There aren't any more rows to retrieve. (The error returned would be different if you hadn't issued the call to the finish() method; the error message would be something about fetching past the end of the cursor, or already fetched last row, or something to that effect.)

Returning MySQL results as hash tables in Perl

In Perl I'm making an SQL query akin to the following:
SELECT `id`, `title`, `price` FROM `gamelist`
What I wish to do is take the result of this query and dump it into a hash table. I am using DBI and currently I only know how to do the following:
my %results;
my $count = 0;
while( #result = $statement->fetchrow() ){
%results{'id'}[$count] = $result[0];
%results{'title'}[$count] = $result[1];
%results{'price'}[$count] = $result[2];
$count++;
}
However I don't like using $result[0] and trusting that the first field will be the ID. I would much rather have something like:
my %results;
my $count = 0;
while( %result = $statement->fetchrow_as_hashtable() ){
%results{'id'}[$count] = %result{'id'};
%results{'title'}[$count] = %result{'title'};
%results{'price'}[$count] = %result{'price'};
$count++;
}
I tried looking around on Google but couldn't find many good answers built into DBI/Perl. I did find an open-source class that offered this functionality, but I feel like this should be possible without the use of someone else's class.
What about fetchrow_hashref?
while (my $result = $statement->fetchrow_hashref) {
print $result->{id};
print $result->{title};
print $result->{price};
}
Use fetchrow_hashref to have the result directly in a hash
Consult the DBI documentation for this use of selectall_arrayref:
$rows = $dbh->selectall_arrayref($query, {Slice=>{}}, #params)
$rows is an Array of Hashes.