PDO fetch me a fake result - php

I'm working on a function that compare two price.
I have a table called 'PRODUCT' that has 3 column: ID, REFERENCE, PRICE.
I get a price from a FORM that i will compare with the column PRICE. If the number that i get with the form, is different by PRICE from the table, i want get the REFERENCE. So i work in this way:
$pdo = new PDO ("mysql:host=$hostname;dbname=$dbname", $user, $pass);
$sql = "SELECT count(1) as NB
FROM ww_ps_product
WHERE reference = :reference AND SUBSTR(wholesale_price , 1, INSTR(wholesale_price ,'.')+2) != :price" ;
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':reference', **$referenza**, PDO::PARAM_STR);
$stmt->bindValue(':price', **$prezzoAggiornato**);
$stmt->execute();
$product = $stmt->fetch(PDO::FETCH_ASSOC);
The value that i get from the form : $referenza is FIN 260482300000 and the $prezzoAggiornato is 6.90 . Normalli, in my $product, i should have 0 but i get 1.
This data are store in DB with the same values:
When i go to compare with my function, i get NB = 1 but that's is impossible. If i check with the same values in phpMyAdmin i get NB = 0.
There is something wrong in my code?

Related

How to find out how many rows match a rule?

I want to find out how many rows in a table of my database meet a certain rule, specifically that "category" matches another variable and "published" is today or earlier. Then I want to simply echo that number.
I have no idea how to go about doing this, though.
I thought I could use count() but I'm not sure how to call just a single column and put the results of each row in an array.
Thanks!
Do this using SQL:
Try this in your database (your columns/tables may be different):
SELECT count(*) FROM blog_posts WHERE category = 'hot_stuff' and published <= NOW();
Then to execute this in PHP, depending on your framework and connection to the database:
$myCategory = 'hot_stuff';
$myTable = 'blog_posts';
$sql = "SELECT count(*) FROM {$myTable} WHERE category = '{$myCategory}' and published <= NOW();";
$rowCount = $db->query($sql);
echo $rowCount;
Connect to your database.
$pdo = new PDO($dsn, $user, $password);
Create a prepared statement. This is essential because you need to pass a value for category from your application to the query. It is not necessary to pass a value for the current date because the database can provide that for you. The ? is a placeholder where the parameter you pass will be bound.
$stmt = $pdo->prepare("SELECT COUNT(*) FROM your_table
WHERE category = ? AND published <= CURDATE()");
Do not concatenate the parameter into your SQL string (like WHERE category = '$category') because this will create an SQL injection vulnerability.
Execute the prepared statement using your specified value for category.
$stmt->execute([$category]); // assuming you have already defined $category
Use fetchColumn to return a single value, the count of rows that matched your criteria.
echo $stmt->fetchColumn();

prepared statement where value is in array

In a php page, I have an array, similar to this:
$category = array(16, 22, 23);
Then I am doing a database query with a prepared statement. I would like to get all rows where the field category contains one of the values from that $category array and where price is lower than a value stored in the variable $price.
Among others I read the answers to this question and tried to use find_in_set() as described there (and at a lot of other places), but somehow I can't make it work within the prepared statement. I tried this:
/* database connection "$db" is established beforehand and works */
if($ps = $db->prepare("
SELECT id, product, category, price
FROM products
WHERE price <= ? and find_in_set(?, category)
ORDER BY id") {
$ps->bind_param("ds", $price, $category);
$ps->execute();
$ps->bind_result($id, $name, $cat, $pr);
while($ps->fetch()) {
/* ... echo the results ..... */
}
$ps->free_result();
$ps->close();
}
But I get an empty result.
If I try to use "dd" or "di" instead of "ds" in the bind_param() line, I do get results, but the wrong ones - I get all rows with category 1.
I also tried to use category IN ? instead of find_in_set(?, category), but that won't work either.
What can I do to make that work? Any help appreciated!
Two issues:
The list should be passed as second argument to find_in_set, so it should be:
find_in_set(category, ?)
That argument should be of type string (comma separated values). So first convert your array to such a string with implode:
$csv = implode(",", $category);
Code:
if($ps = $db->prepare("
SELECT id, product, category, price
FROM products
WHERE price <= ? and find_in_set(category, ?)
ORDER BY id") {
$csv = implode(",", $category);
$ps->bind_param("ds", $price, $csv);
$ps->execute();
$ps->bind_result($id, $name, $cat, $pr);
while($ps->fetch()) {
/* ... echo the results ..... */
}
$ps->free_result();
$ps->close();
}
If you want to find values where $category belongs to a certain set try using IN. Just a note you cannot pass an array into a string like you have above.
Also don't forget to convert your array to a CSV string using implode
$category = array(16, 22, 23);
$cat_str = implode(",",$category); //16,22,23
$ps = $db->prepare("
SELECT id, product, category, price
FROM products
WHERE price <= ? and category IN (?)
ORDER BY id") {
$ps->bind_param("ds", $price, $cat_str);
if i tried the same case , then i would probably have done it like this
SELECT id, product, category, price
FROM products
WHERE category = '16' || category = '22' || category = '23' and price < $price`
i am assuming your $category array variable is fixed , it's not dynamically appending value .
I answered only your query part . i'd hope you have php coding convention idea rather than putting the entire statement in the if statement .
if still has anything to ask about , please go ahead

How to get the last inserted id, and the name of the column with PDO?

I'm building a QueryBuilder where you can insert dynamically, after that I would like to return the last row inserted, so far I'm getting the last inserted Id with pdo.
$last_id = $this->pdo->lastInsertId();
After that i need to do a query
$statement = $this->pdo->prepare("SELECT * FROM {$table_name} WHERE id = :id");
The problem is that my column
Id
Doesn't call like that all the time, sometimes it name is id_user or id_work, etc.
What i need is to get the column name of where PDO is getting the last Id.
No direct way to know the field name, and there are two solutions.
1) If less tables, you can build an array to save the "id" field directly. for example :
$tables = ["table_1" : "id_user", "table_2" : "id_work"]
and you can use the $tables[$table_name] instead of the id in your SQL.
2) If you don't know which tables will be used, you can analysis the table directly via PDO before you generate the query sql.
For example
$stmt = $pdo->prepare('DESC tablename');
$stmt->execute();
$table_fields = $stmt->fetchAll(PDO::FETCH_COLUMN);
foreach($table_fields as $field){
if($field["Extra"] == "auto_increment"){
$field_id_name = $field["Field"];
break;
}
}

Getting record from database that has empty field

I have the following lines of code to retrieve records from a database:
$dbh = new PDO("mysql:host=$hostname;dbname=$dbname; charset=utf8;", $username, $password);
$sql = $dbh->prepare("SELECT * FROM usa WHERE code = :code AND window1 = :oldrepeat AND spare <> :americinn AND url IS NOT NULL ORDER BY user ASC");
$sql->execute(array(':code' => $code, ':oldrepeat' => $oldrepeat, ':americinn' =>$americinn));
/*** fetch the results ***/
$result = $sql->fetch();
Amongst other criteria, this query is supposed to return records that only have some content in the field called url, but this is not happening. It is returning records that also have an empty url field.
I assume that I am doing something fundamentally wrong but cannot see what it is.
Can anyone shed some light please?
Best wishes
Well, write your query in following way:
SELECT * FROM usa WHERE code = :code AND window1 = :oldrepeat AND spare <> :americinn AND !ISNULL(url) ORDER BY user ASC
ISNULL is an inbuilt MySQL function that checks if value of a column is null. By using ! (negation), you will get only required rows.
In case if a column has blank value, you can try url!=''.

PDO compare 2 fields

probably a simple case. Basically I have a Database with 5 fields, which are showing Orders and their progress:
idRefs, Quantity, refsDone, refsRunning, refsUntouched
Now I want to select all those Rows, where Quantity = refsDone (this means the order is done). I am wondering how I can do this using PDO ? This is what I've tried:
$filter = $_POST['filter'];
$limiter = $_POST['limiter'];
$refid = $_POST['refid'];
if($refid == "") $refid="%";
case("finished"):
$sql = "SELECT * FROM Orders WHERE REFID LIKE :refid AND quantity=refsDone ORDER BY dateAdded DESC LIMIT :min,:max";
$ps_orders = $db->prepare($sql);
$ps_orders->bindParam(':refid', $refid, PDO::PARAM_STR);
$ps_orders->bindParam(':min', $min, PDO::PARAM_INT);
$ps_orders->bindParam(':max', $limiter, PDO::PARAM_INT);
$ps_orders->execute();
$rowCount = $ps_orders->fetchColumn();
$data = $ps_orders->fetchAll();
break;
Cant say whats happening wrong, but I am kinda sure it is the part "AND quantity=refsDone" which causes it.
I tested your query in this SQLFiddle: http://sqlfiddle.com/#!2/32ae40/8
The query returns an empty set in several cases:
if $refid is null
if $refid is empty string ('')
if $min is 1 or more
if $limiter is 0
I think you should make sure your variables are values you expect them to be, because if they aren't the query is likely to return an empty set.
You can troubleshoot parameterized queries yourself by enabling the MySQL general query log, which logs both the prepared query and the query with parameter values included.

Categories