Simple perl mysql query not working - mysql

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.

Related

Comparing List of regex to a string

i have question i don't know better approach to do it in mysql. I have a table in mysql with list of regex's each regex represent a company order number
i want to be able to compare a number to that list to get which company this number belongs to. the lazy way is to list all the regex in php and then using loop to get the company , but i want to do this using the power of mysql .
Like #Mech mention this might be vague.
i will try to explain it more :
I have two tables table with actual regex pattern in plain text in a column like "^[8]{1}[0-9]{10}$"
and this pattern belong to a company , there is more than 500 regex patterns .
Thank you.
Here you go #BM2ilabs. A function as requested :)
carrierID(88888141234);
function carrierID($ordernum) {
// create a connection to your db here
// fetch data needed for loop
$sql = "SELECT regex, carrier_id FROM `company_tbl_from_image`";
// fetch results
$results = $conn->query($sql);
// loop through $results
foreach ($results as $result) {
// individually check against each regex in the table
$regex = $result[regex];
// find first instance of $regex, where the $ordernum is unique, there should only be one match
if (preg_match('/'.$regex.'/', $ordernum)) {
$carrier_id = $result[carrier_id];
break; // remove break to show other matches
}
}
// check if $carrier_id is empty
if ($carrier_id <> "") {
echo $carrier_id;
} else {
echo "No carrier ID found.";
}
}
MySQL only option. Just search this:
SELECT carrier_id FROM `company_tbl_from_image` WHERE 'order number' REGEXP regex

perl DBI, fastest way to get a single scalar value

I have this code to get a value count.
Short way:
my $count = $dbh->selectrow_array("SELECT COUNT(name) AS RESCOUNT FROM users");
Long way
my $sth = $dbh->prepare("SELECT COUNT(name) AS RESCOUNT FROM users");
$sth->execute() or die "$DBI::errstr";
my $count = $sth->fetchrow_array();
$sth->finish;
selectrow_array, fetchrow_array --> but I don't need an array. I checked the docs, but found nothing for scalars. Just methods for arrays and hashes.
The method I use is fast enough, but I was just curious if there is a better, fastest way to get a single value from the call. Or this is the fastest possible way?
The fastest way is to use fetchrow_arrayref or selectrow_arrayref, depending on how many executes you have. This only really makes a difference if executed in a loop and you have thousands (or rather hundreds of thousands) of rows.
When using fetchrow_array, it will make a copy every time, which slows you down. Also keep in mind that the behaviour for scalar context is only partly defined.
If called in a scalar context for a statement handle that has more than one column, it is undefined whether the driver will return the value of the first column or the last. So don't do that.
You can also do bind_col, which works with references.
There used to be a good presentation on DBI speeds from about 10 or more years ago that I can't find right now. Also take a look at this very old Perlmonks post, that explains quite a bit about performance.
Keep in mind that you should only do optimisation when you really know you need it. Most of the time you won't.
If "modern" means "I only heard of it recently", I'm feeling all modern with DBI's bind_col and bind_columns. Cribbing from a post by DBI hero Tim Bunce...
For your case:
my $sth = $dbh->prepare("SELECT COUNT(name) AS RESCOUNT FROM users");
my $count = 0;
$sth->bind_col(1,\$count); # bind to a reference to the variable
$sth->execute() or die "$DBI::errstr";
$sth->fetch;
print $count;
In a loop for a SELECT statement returning multiple records:
my $sth = $dbh->prepare(qq{SELECT name FROM users WHERE zip_code == '20500'});
my $name = '';
$sth->bind_col(1,\$name); # bind to a reference to the variable
$sth->execute() or die "$DBI::errstr";
while ($sth->fetch) {
print $name, "\n";
}
And with bind_columns this works:
my $sth = $dbh->prepare(qq{SELECT name,phone,address FROM users WHERE zip_code == '20500'});
my #fields = qw/name phone address/;
# With a 'SELECT All * ...', get all columns with #{$sth->{NAME_lc}}
my %data;
$sth->bind_columns( \( #data{#fields} ) ); # \(...) gives references to its elements
$sth->execute() or die "$DBI::errstr";
while ($sth->fetch) {
print "$data{name} lives at $data{address}, with phone $data{phone}.", "\n";
}
Once the setup is handled, the looping is simple to write and fast to run. (But, benchmark).
HTH, apologize if this diverges too much from the OP's problem statement. But it's the simplest and most direct way to get your returned data into the form of variable(s) you want, so you can move on to doing something with it...

In CakePHP 3.x how can I count the number of rows in a MySql table?

I have a MYSQL table called 'devices'. I've successfully done the bin/cake bake all. In fact I have the auto-built DevicesController.php fully working. But I can't figure out how to count the rows in a table. I've tried:
$conn = ConnectionManager::get('default');
$numRows = $conn->execute('select count(*) from devices');
and
$this->DeviceSetups = TableRegistry::get('Devices');
$numRows = $this->Devices->query('select count(*) from devices'); // both like this
$numRows = $this->Devices->query('select count(*) from devices')->execute(); // and like this
and
$this->DeviceSetups = TableRegistry::get('Devices');
$numRows = $this->Devices->find('count');
Going thru mysql_query() isn't really a good idea because I have all the access info already setup in app.php for CakePHP to use. I tried something else using AnyModel that didn't work.
The former 2 attempts return a Cake\Database\Statement\MysqlStatement not an integer with the number of rows in the table. I've consulted this answer and this answer and read the CakePHP docs. Nothing seems to tell me how to count up a table nor how to execute a raw My SQL command string and then access the result.
TableRegistry::get('DeviceSetups')->find()->count();
See http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets.html#getting-a-count-of-results.
If you want to count in table then it should be like below.
$count = $this->find()->count();
echo $count;

fetchrow_hashref issue in perl

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 = '';
}

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.