I have a site with products I sell and each product has its own product code. The problem is that recently we changed all product codes to all products.
Because all sales inserted in MySQL before today used the old product code, when I try to get a report to see how many of one product has been sold system find 0 because it looks for the new product code while older sales was inserted with the old one.
Solution:
Even if it is a pain there is no other way than updating all products sold and inserted in MySQL updating the old product code with the new one this way it will work fine.
I need to update like this:
$update = mysqli_query($database, "
update `sales` SET code = 0001 WHERE `code` = '4574645448458'
");
The only problem is that it updates only the first product with this product code but I have houndreds of products sold with the same product code...
How to solve this in some bulk way?
examples of what I will change:
code 4574645448458 for 0001
code 4574645448459 for 0002
and so on
Here is an example of the suggestion from Marc B.
Use a prepared statement and execute it with each pair of "old/new" values.
A prepared statement can be executed repeatedly. Upon every execution the current value of the bound variable is evaluated and sent to the server. The statement is not parsed again. The statement template is not transferred to the server again.
For example:
// define an array with all of the code changes as "key/value" pairs
$changes=array(
'4574645448458' => '0001',
'4574645448459' => '0002',
....
);
// define the query string with placeholders
$sql="UPDATE `sales` SET `code`=:new_code WHERE `code`=:old_code;";
// prepare the statement and set up variables to be bound upon execution
$q=$database->prepare($sql);
$q->bind_param(':new_code',$new_code);
$q->bind_param(':old_code',$old_code);
// iterate through "changes", defining the "old" and "new" values for each code change
// execute the prepared statement with each pair of values
foreach ($changes as $old_code => $new_code) {
$q->execute();
}
Related
I'm new at PHP so please dont bust my chops.
I'm building a Knowledge base system, basic CRUD functionality. I'm getting stuck where i need to NULL all values for each column in a table.
This is basically the "Edit a KB" form. I have a checkbox array which on edit I want to clear the KB number from my category column on my table 'category_kb_members'.
My code works fine apart from this bit.
This is my current code:
//Clear all categories for this KB
while($catrow = mysqli_fetch_array($categorylist)){
$catname = "";
$catname = $catrow['name'];
mysqli_query ($dbc, "UPDATE category_kb_members SET $catname=NULL WHERE $catname ='$kbid';");
}
[Please note no need to comment abut SQL injection here as the source is clean from the database.]
"$Categorylist" is an array of Category names - the table I am updating has a column for each category.
"$kbid" is set from a $_GET from the URL and corresponds with the KB number to be removed and is valid and working.
My loop is to query and update each column to NULL the KB number if it exists in the column. The code later goes on to add these back in the the relevant columns.
I have run this query against MYSQL and it works fine SQL side.
Any ideas as to why the UPDATE is not working?
Thanks for all you're comments. Credits to all who assisted.
I copied my query for $catname
$categorylist = mysqli_query($dbc,"SELECT name FROM categories");
which was further up the code. Although this variable was already set, and working for above code it must have been cleared somewhere above in my code. If I re-run this part above my loop it works fine. I will have to figure out what is overwritting my variable above.
Thanks to all and "Abdulla" for making me think for a 3rd time.
I have a php file which generates a webshop layout.The problem is when I started to split the products to pages. I have the following query wich runs in the products database where every kind of product can be found. There is a prodducttype column which specifies under which menu it should be displayed.
The query
$sql = "SELECT id,descr, nm, img, price FROM c1640644.products WHERE
producttype = '".$GLOBALS["useableproductid"]."' LIMIT ".($start- 1).",".$stop;
There is one row which always missing
I used echo to display the query just before running it its the following:
SELECT id,descr, nm, img, price FROM c1640644.products WHERE
producttype = 'laptop' LIMIT 0,8
Briefly about the database:
Currently 3 types of products laptops, headphones, desktops.
When displaying laptops they are from ID 1- 17 and ID=1 is missing. Headphones from ID 18-22 and ID=21 is missing. Desktops from ID 23-27 and ID=23 is missing. Always the same products are missing.
The displaying method is:
while($row = $result->fetch_assoc()){
echo $row["nm"]; //just an example echo in the code it gets displayed with design
...
}
Thank you for all the answers!
The most reasonable explanation for the observed behavior ("missing" row for 'laptop' and a "missing" row for 'headphone') is that the rows do not satisfy the predicate, equality comparison to producttype. (This assumes there are fewer than $stop-$start rows is being returned.
I'd verify the values of producttype.
SELECT producttype, COUNT(1)
FROM c1640644.products
GROUP BY producttype
ORDER BY producttype
Is the count returned equal to the number of rows you expect to be returned? In particular, I'd look for values that are visually close to "laptop", but would not satisfy an equality match, such as 'laptop ultra-portable', or 'lapt0p'. Those values would not satisfy an equality comparison to 'laptop'.
Without an ORDER BY clause, MySQL is free to return rows in any order. The result from the query with the LIMIT clause is indeterminate. It's possible that a query with LIMIT 0,8 and LIMIT 8,16 may include the same row. It's also possible that a row will be "skipped".
If the case is that there is always "one row missing", I'm suspicious that there's a fetch before the while loop. The loop shown in the question looks right. It's also possible that nm column contains an empty string, and it makes it look like a row is "skipped". For debugging that, consider including echo "row fetched"; as the first line inside the loop. Or initializing a counter variable before the loop $i=0;, and then inside the loop, increment $i and include $i in the string that in the debug output.
I'm trying to execute 2 queries, but whenever I follow the guides online about multi queries, its not doing either of the queries.
What I'm trying to do on the first query is to INSERT or ADD whatever the user inputs on $HISTORY on the record that's currently on colHistory; I.E.:
Current data on colHistory:
A
User inputs 'B' on $HISTORY, the syntax should add 'B' on the 'A' that's currently on record, or 'AB'. Then use the second query to UPDATE all the other records or columns on this particular row.
Here's the code (Please note that the '...' means more code that's unnecessary):
$query = INSERT INTO tbInventory SET colHistory='$HISTORY' WHERE colSerno='$SERIALNUM';";
$query .= "UPDATE tbInventory SET
colImage='$IMAGE',
colSerno='$SERIALNUM',
...
...
colHistory=''
WHERE colSerno='$SERIALNUM'";
mysqli_multi_query($con,$query);
Please note where I declared colHistory as '' before I insert the data from the form. I'm not sure if I'm doing it right on this part. Is there anything that I'm missing?
*Edit:
I have already tried executing the queries one by one as:
mysqli_query($con,"INSERT INTO tbInventory SET colHistory='$HISTORY' ");
mysqli_query($con,"UPDATE tbInventory SET
...
...
colHistory=''
WHERE colSerno='$SERIALNUM'";
Yet it doesn't seem to work either, the whole thing gets ignored.
(** I have a script below the code block above where I could print the results already, and it does run)
Well I can tell you why your first query is broken.
INSERT INTO tbInventory SET colHistory='$HISTORY'
This query is using UPDATE syntax but you are telling the query processor to expect INSERT INTO syntax. So the query is unable to execute.
Decide whether you are needing to UPDATE an existing record or INSERT a new one and alter your query to reflect that. (Change INSERT INTO to UPDATE or change "Set colHistory = '$ History'" to "Values ('$ History', 'col2Val', and so on..")
As for your second query, the syntax looks alright from what you have shown but since you didn't post the entire query its hard to say what is happening there. If you can show more of that query I can update this response.
Here's a good SO question on inserts vs updates.
What are differences between INSERT and UPDATE in MySQL?
I ended up dropping the multi-query method and I did got my intended results by somehow cheating:
I assigned the old data or the data that's currently on the colHistory cell, displayed it, but I disabled the textarea. I then created one more hidden textbox in the script with the old data in it and then hid it to the users view.
I then concatenated both textareas with the new one that I've created that the user could modify, emulating the results wanted.
I'm currently working on a system to managed my Magic The Gathering collection. I've written a script to update pricing for all the cards utilizing a WHILE loop to do the main update but it takes about 9 hours to update all 28,000 rows on my i5 laptop. I have a feeling the same thing can be accomplished without the While loop using a MySQL query and it would be faster.
My script starts off by creating a temporary table with the same structure as my main inventory table, and then copies new prices into the the temporary table via a csv file. I then use a While loop to compare the cards in temp table to the inventory table via card_name and card_set to do the update.
My question is, would a pure mysql query be faster than using the while loop, and can you help me construct it? Any help would be much appreciated. Here is my code.
<?php
set_time_limit(0);
echo "Prices Are Updating. This can Take Up To 8 Hours or More";
include('db_connection.php');
mysql_query("CREATE TABLE price_table LIKE inventory;");
//Upload Data
mysql_query("LOAD DATA INFILE 'c:/xampp/htdocs/mtgtradedesig/price_update/priceupdate.csv'
INTO TABLE price_table FIELDS TERMINATED BY ',' ENCLOSED BY '\"' (id, card_name, card_set, price)");
echo mysql_error();
//UPDATE PRICING
//SELECT all from table named price update
$sql_price_table = "SELECT * FROM price_table";
$prices = mysql_query($sql_price_table);
//Start While Loop to update prices. Do this by putting everything from price table into an array and one entry at a time match the array value to a value in inventory and update.
while($cards = mysql_fetch_assoc($prices)){
$card_name = mysql_real_escape_string($cards['card_name']);
$card_set = mysql_real_escape_string($cards['card_set']);
$card_price = $cards['price'];
$foil_price = $cards['price'] * 2;
//Update prices for non-foil in temp_inventory
mysql_query("UPDATE inventory SET price='$card_price' WHERE card_name='$card_name' AND card_set='$card_set' and foil ='0'");
//Update prices for foil in temp_inventory
mysql_query("UPDATE inventory SET price='$foil_price' WHERE card_name='$card_name' AND card_set='$card_set' and foil ='1'");
}
mysql_query("DROP TABLE price_table");
unlink('c:/xampp/htdocs/mtgtradedesign/price_update/priceupdate.csv');
header("Location: http://localhost/mtgtradedesign/index.php");
?>
The easiest remedy is to perform a join between the tables, and update all rows at once. You will then only need to run two queries, one for foil and one for non foil. You can get it done to one but that gets more complicated.
UPDATE inventory i
JOIN price_table pt
ON (i.card_name = pt.card_name AND i.card_set = pt.card_set)
SET i.price = pt.card_price WHERE foil = 0;
Didn't actually test this but it should generally be what your looking for. Also before running these try using EXPLAIN to see how bad the join performance will be. You might benefit from adding an indexes to the tables.
On a side note (and this isn't really your question) but mysql_real_escape_string is deprecated, and in general you should not use any of the built in php mysql functions as they are all known to be unsafe. Php docs recommend using PDO instead.
In our cart process we don't want to remove items from the store inventory until after the payment gateway has returned a approved code for the credit card purchase. Thus assuming the payment was approved we need the cart items to deduct from the inventory.
In a mysqli UPDATE query how if possible can i write it so that the new value being set is the result of the rows current value - the quantity stored in the carts Item_qty field?
mysqli_query($con,"UPDATE table1 SET Qty='`**current-value**` - $proc[Item_Qty]' WHERE buyer='$user'");
I do understand that I can accomplish this using multiple queries, perform some math and then write the value back to the database, but I am hoping there is a cleaner way with less code by doing all in a single mysqli query.
You can use current values of the table in an update.
mysqli_query($con,"UPDATE table1 SET Qty = Qty - $proc[Item_Qty] WHERE buyer='$user'");
Easy. You can use the field itself in the calculation:
UPDATE table1 SEt Qty=Qty - $proc[Item_Qty]
^^^--- this is 100% perfectly valid
This should do it:
$query = "UPDATE table1 SET Qty = Qty - $proc[Item_Qty] WHERE buyer='$user'";
You are simply, using the field name again to get its current value.