A database lists items and their stock count. When someone buys items I wish to update the stock count in the database.
Regardless of the following subtraction f_item_number = f_item_number - $mugAmount, my update statement isn't working.
If I have 200 mugs in the database. When I run the following statement the new mug amount is listed incorrectly afterwards as -1. Rather than the expected value of 199. Why is this?
DB::update('UPDATE `shop_items` SET `f_item_number` = ? WHERE `f_item_name` = ?', array(`f_item_number` - $mugAmount, "mug"));
You can't pass in database column text in the parameters. Try this
DB::update('UPDATE `shop_items` SET `f_item_number` = `f_item_number` - ? WHERE `f_item_name` = ?', array($mugAmount, "mug"));
Related
I have a user form that sets a single record "current". No more than one record can be set to current at a time. So, I present the user a single drop down list, they choose the item they want to set current and hit "UPDATE" at the bottom of the form.
The PHP/Mysqli needs to go in and set all records column "current" to a value of 0 then update the one from the form to a value of "1".
Initially, I just did a simple count the number of rows, and run a bunch of queries to update the column to 0 or 1 if the loop counter = the id of the row. Well... that broke quick as I started doing testing on other portions and the index numbers got higher than the total number of rows. Yes, dumb way to do it initially!
Here's what I tried to do with the PHP / MySQL code:
// $link is the database link defined elsewhere. This does work as I use it all over the place
$setCurrent = X; // This is the number passed from my form
$init_query = "SELECT id, current FROM myTable";
if ($stmt = $link->$prepare($init_query) {
$stmt->execute() or die ($stmt->error);
$stmt ->bind_result($id, $current)
while ($stmt->fetch()){
if ($id == $setCurrent){
$update_sql = "UPDATE myTable SET current ='1' WHERE id='".$setCurrent."'";
$stmt2 = $link->prepare($update_sql);
$stmt2->execute;
}
else {
$update_sql = "UPDATE myTable SET current ='0' WHERE id='".$id."'";
$stmt2 = $link->prepare($update_sql);
$stmt2->execute;
}
$stmt->close();
This fails and gives me a Fatal error: Uncaught Error: Call to a member function execute on boolean in .....
I am racking my brain over this and can't figure out what the heck is going on. Its been a few years since I have worked in PHP/MySql and this is my first forray into OO Mysqli. Please be gentle :)
You're missing two closing curly braces. One for the first if() and the other for while()
why do them one at a time? You can do it in one query
$setCurrent = X;
$query = 'UPDATE myTable
SET `current` = (id = :current)';
$stmt = $link->prepare($query);
$stmt->bindValue(':current', $setCurrent);
$stmt->execute();
(and misusing the fact that if id equals $setCurrent, the part between ( ) resolves to true, which is 1.)
some explaining:
SELECT 10=10; would give a kind of "TRUE". But as Mysql does not give true, it give 1.
the same goes for:
SELECT 10=20; This is FALSE, so gives you 0.
Now back to your query: you want to get a value 0 for all record for which id not equal to some-number. And you want 1 when equal:
So you have to compare the column id's value to $setCurrent. When they match you get 1 and you put that 1 into the column "current"
And when they don't match, all other cases, then you get a 0 and that 0 goes into the column Current.
And yes, this could also be done as:
UPDATE mytable
SET `current` = CASE id
WHEN $setCurrent THEN 1
ELSE 0
END CASE
or using IF,
But they other syntax is way shorter
edit
backtics are needed around column name, as current is a reserved word
we have a table "products" with two columns name code and price , i update this table with where code = "something" condition ,
$sql = "UPDATE products SET price='20' WHERE code=2";
and easily update price . but we want our query check , if our uploaded data is lower than old data , then our value will not update , and if our uploaded data is greater than old value of price , then price updated ., means we want always price value is maximum ??what is way...
You can specify the condition in the filter:
UPDATE products SET price = 20 WHERE code = 2 AND price < 20
Or else, you can use MySQL's GREATEST() function:
UPDATE products SET price = GREATEST(price, 20) WHERE code = 2
I try to build a variable that integrates some other variable.
one of that will be the number of an auto-increment-field where later on an insert-query will happens.
I tried to use:
$get_num = $db/*=>mysqli*/->query("SELECT COUNT (*) auto_increment_column FROM table1");
$num = $query->fetch_assoc($get_num);
$end = $num + 1;
I don't have any update/insert query before that so I can't use
$end = $db->insert_id;
that's why i thought i can just count the numbers of the auto_increment rows and have my last variable that is necessary to build my new variable.
for a reason this wonT count the entries and outputs 0. i dont understand why this happens.
i really would appreciate if there is someone who could tell me what am i doing wrong. thanks a lot.
UPDATE
For everyone who likes to know about what's the goal:
I like to create a specific name or id for a file that later on will be created by the input of the fields from the insert query. I like to have an unique key. this key consists of an user_id and a timestamp. at the end of this generated variable it should be placed the auto_increment nr. of the query that will be placed in the table. so the problem is, that I create an variable before the insert query happens so that this variable will be part of the insert query like:
$get_num = $db->query("SELECT COUNT (*) FROM tableA");
$num = $query->fetch_assoc();
$end = $num + 1;
$file_id = $id .".". time() .".". $end;
$insert = $db->query("INSERT INTO tableA ( file_id, a, b, c) VALUES('".$file_id."','".$a."','".$b."','".c."')");{
hope now, it will be clear what I like to approach.
If you need an auto-incrementing column in MySQL then you should use AUTO_INCREMENT. It implements it all for you and avoids race conditions. The manual way you are trying to implement it has a couple of flaws, namely
If two scripts are trying to insert concurrently they might both get the same COUNT (say 10) and hence both try to insert with ID 11. One will then fail (or else you will have duplicates!)
If you add 10 items but then delete item 1, the COUNT will return 9 but id 10 will already exist.
try
SELECT COUNT(*) FROM table1
How could I simplify this update instruction? Whenever a client buys an item it will update the sales with 1.
$this->db->query('SELECT amount FROM shop_items WHERE itemid='.$itemid.'');
$new_amount = $item->amount+1;
if(!$this->db->query('UPDATE shop_items SET amount='.$new_amount.' WHERE itemid='.$itemid.'')):
return false;
endif;
Can't I make it more simple so there are less lines, for example:
if(!$this->db->query('UPDATE shop_items SET amount=_current_value_+1 WHERE itemid='.$itemid.'')):
return false;
endif;
is this possible? if not thanks anyway
What about using the following SQL query :
update shop_items
set amount = amount + 1
where itemid = 123
Basically, in just one SQL query, you set the amount to the previous value it had, plus one.
No need for two queries ;-)
Integrating this in your PHP code should give you something that looks like this :
if (!$this->db->query('UPDATE shop_items SET amount=amount+1 WHERE itemid='.$itemid.'')) :
return false;
endif;
Note : I just replaced your _current_value_ by the name of the field that you're working on : amount.
Hey, I have a field called STATUS and it is either 1 to show or 0 to hide. My code is below. I am using an edit in place editor with jQuery. Everytime you update it creates a new ROW which I want, but I want only the new one to have STATUS = 1 and the others to 0. Any ideas on how I would do that?
<?php
include "../../inc/config.inc.php";
$temp = explode("_", $_REQUEST['element_id'] );
$field = $temp[0];
$id = $temp[1];
$textboxval = stripslashes(mysql_real_escape_string(preg_replace('/[\$]/',"",$_REQUEST["update_value"])));
$query = "INSERT INTO notes ($field,status,date,c_id) VALUES ('$textboxval','1',NOW(),'$id')";
mysql_query($query);
echo($_REQUEST['update_value']);
?>
I am not sure exactly what you mean - do you want to make all the entries except the new one have status = 0? If so, just issue an update before the insert:
UPDATE notes SET status = 0
However, I should also note that you have a potential SQL injection to worry about. By stripping slashes after applying "mysql real escape string", you are potentially allowing someone to put text in your SQL statement that will execute an arbitrary SQL statement.
Something like this, sorry for the post before, I mis read it the first time then went back:
<?php
include "../../inc/config.inc.php";
$temp = explode("_", $_REQUEST['element_id'] );
$field = $temp[0];
$id = $temp[1];
$textboxval = mysql_real_escape_stringstripslashes((preg_replace('/[\$]/',"",$_REQUEST["update_value"])));
// set older entries to 0 - to not show but show in history
$hide_notes = "UPDATE notes SET status = 0";
mysql_query($hide_notes);
// add new entry with status of 1 to show only latest note
$query = "INSERT INTO notes ($field,status,date,c_id) VALUES ('$textboxval','1',NOW(),'$id')";
mysql_query($query);
echo($_REQUEST['update_value']);
?>
i just ran in to a problem I didn't of the set up of my table doesn't allow me to show more than one client a time and i will be having numerous clients, my bad on planning ha
You really want to get the ID of the newly generated row and then trigger an UPDATE where you all rows where the ID is not the new row, e.g.
UPDATE notes SET status = 0 WHERE id != $newly_generated_id
If the ID column in your table is using AUTO_INCREMENT you can get its ID via "SELECT LAST_INSERT_ID()" and then use the return value in that statement in your UPDATE statement.
Pseudo code:
$insert = mysql_query("INSERT INTO ...");
$last_id = mysql_query("SELECT LAST_INSERT_ID()");
$update = mysql_quqery("UPDATE notes SET status = 0 WHERE id != $last_id");
The only caveat to this approach is where you might have a brief moment in time where 2 rows have status=1 (the time between your INSERT and the UPDATE). I would wrap all of this in a transaction to make the whole unit more atomic.