Mysql Table Update operation failing for no apparent reason - php

I have written some PHP/mysql code for a form-based subtitling program -- but there is one field in particular that I cannot get MYSQL to UPDATE for me. I have been looking for the problem for hours and I just can't find it. Below is, I think, the most relevant piece of code for resolving the problem. The field in question (TotalSeconds) definitely exists on the 'captions' table and, as the comments show below, the $TotalSeconds string also exists (at least prior to the update attempt) -- and yet all attempts to update the TotalSeconds field with the $TotalSeconds string value are failing. The TotalSeconds field, by the way, is of the type DECIMAL(11,3) (which must be related to my problem, since I'm new to using that field type).
$TotalSeconds=$_REQUEST['TotalSeconds'];
/* NOTE: I can get the TotalSeconds string variable to echo successfully before the update attempt below */
$result=mysql_query("UPDATE captions SET TotalSeconds='$TotalSeconds' WHERE ID='ThisID'") or die(mysql_error());
$k=mysql_affected_rows();
And yet the UPDATE operation above never works. The affected rows value always = 0. And yet I have nine other fields which are set to update the same way, and none of the others give me any trouble at all.
Any ideas would be greatly appreciated.
Thanks,
Brian

OP says there was a typo.
(Now, not 'Unanswered'.)

Related

Issue with maintaining a MySQL WooCommerce Customer Table

Well, I'm afraid that I will not be able to post a minimum reproducible example, and for that I apologize. But, here goes nothing.
Ours is a weekly prepared meals service. I track order volume in many ways. Here is the structure of the relevant table:
So then I utilize the highlighted fields in many ways, such as indicating to delivery drivers if a customer is returning from the prior order being more than a month ago (last_order_w - prev_order_w > 4), for instance.
Lately I have been noticing that the data is not consistently updating properly. In the past 3 weeks, I would say it is an occurrence of 5%. If it were more consistent, I would be more confident in my ability to track down the issue, but I am not even sure how to provoke it, as I only really notice it after the fact.
The code that should cause the update is below:
<?php
//retrieve and iterate over IDs of orders placed since last synchronization.
$newOrders=array_map('reset',$dbh->query("select id from wp_posts where id > (select max(synced) from fitaf_weeks) and post_type='shop_order' and post_status='wc-processing'")->fetchAll(PDO::FETCH_NUM));
foreach($newOrders as $no){
//retrieve the metadata for the current order
$newMetas=array_map('reset',$dbh->query("select meta_key,meta_value from wp_postmeta where post_id=$no")->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE));
//check if the current order is associated with an existing customer
$exist=$dbh->query("select * from fitaf_customers where id=".$newMetas['_customer_user'])->fetch();
//if not, gather the information we want to store from this post
$noExist=[$newMetas['_customer_user'],$newMetas['_shipping_first_name'],$newMetas['_shipping_last_name'],$newMetas['_shipping_address_1'],(strlen($newMetas['_shipping_address_2'])==0?NULL:$newMetas['_shipping_address_2']),$newMetas['_shipping_city'],$newMetas['_shipping_state'],$newMetas['_shipping_postcode'],$phone,$newMetas['_billing_email'],1,1,$no,$newMetas['_paid_date'],$week[3],$newMetas['_order_total']];
if($exist){
//if we found a record in the customer table, retrieve the data we want to modify
$oldO=$dbh->query("select last_order_id,last_order,last_order_w,lo,num_orders from fitaf_customers where id=".$newMetas['_customer_user'])->fetch(PDO::FETCH_GROUP|PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE);
//make changes to the retrieved data, and make sure we are storing the most recently used delivery address and prepare the data points for the update command
$exists=[$phone,$newMetas['_shipping_first_name'],$newMetas['_shipping_last_name'],$newMetas['_shipping_postcode'],$newMetas['_shipping_address_1'],(strlen($newMetas['_shipping_address_2'])==0?NULL:$newMetas['_shipping_address_2']),$newMetas['_shipping_city'],$newMetas['_shipping_state'],$newMetas['_paid_date'],$no,$week[3],$oldO['last_order'],$oldO['last_order_id'],$oldO['last_order_w'],($oldO['num_orders']+1),($oldO['lo']+$newMetas['_order_total']),$newMetas['_customer_user']];
}
if(!$exist){
//if the customer did not exist, perform an insert
$dbh->prepare("insert into fitaf_customers(id,fname,lname,addr1,addr2,city,state,zip,phone,email,num_orders,num_weeks,last_order_id,last_order,last_order_w,lo) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)")->execute($noExist);
}
else{
//if the customer did exist, update their data
$dbh->prepare("update fitaf_customers set phone=?,fname=?,lname=?,zip=?,addr1=?,addr2=?,city=?,`state`=?,last_order=?,last_order_id=?,last_order_w=?,prev_order=?,prev_order_id=?,prev_order_w=?,num_orders=?,lo=? where id=?")->execute($exists);
}
}
//finally retrieve the most recent post ID and update the field we check against when the syncornization script runs
$lastPlaced=$dbh->query('select max(id) from wp_posts where post_type="shop_order"')->fetch()[0];
$updateSync=$dbh-> query("update fitaf_weeks set synced=$lastPlaced order by id desc limit 1");
?>
Unfortunately I don't have any relevant error logs to show, however, as I documented the code for this post, I realized a potential shortcoming. I should be utilizing the data retrieved from the initial query of new posts, rather than a selecting the highest post id after performing this logic. However, I have timers running on my scripts, and this section hasn't taken over 3 seconds to run in a long time. So it seems unlikely, that the script, which runs on a cron every 5 minutes, is experiencing this unintended overlap?
While I have made the change to pop the highest ID off of $newOrders, and hope it solves the issue, I am still curious to see if anyone has any insights on what could cause this logic to fail at such a low occurrence.
It seems likely your problem comes from race conditions between multiple operations accessing your db.
First of all, your last few lines of code do SELECT MAX(ID) and then uses that value to update something. You Can't Do That™. If somebody else adds a row to that wp_posts table anytime after the entry you think is relevant, you'll use the wrong ID. I don't understand your app well enough to recommend a fix. But I do know this is a serious and notorious problem.
You have another possible race condition as well. Your logic is this:
SELECT something.
make a decision based on what you SELECTED.
INSERT or UPDATE based on that decision.
If some other operation, done by some other user of the db, intervenes between step 1 and step 3, your decision might be wrong.
You fix this with a db transaction. The ->beginTransaction() operation, well, begins the transaction. The ->commit() operation concludes it. And, the SELECT operation you use for step one should say SELECT ... FOR UPDATE.

MySQL multiple condition Type

I'm creating a CMS from scratch.
I'm looking for a way to set a value in my database following a specific condition.
The context here is I want to save records for the deleted or edited comments that would have been reported by the community.
Then I wanna view those logs/records but I have trouble defining wheter or not those values are deleted or edited.
( this is important to view the logs, obviously )
Here is the code i've done so far to insert the logs.
// Insert logs moderation
public function insertLogs($idCommentaire){
$sql ="INSERT INTO logs(com_id, com_date, com_author, com_content, post_id)
SELECT com_id, com_date, com_author, com_content, post_id FROM
comments WHERE com_id = ?";
$this->executeRequest($sql, array($idCommentaire));
}
Now I would like to set it up if it's modified or deleted, depending on which method I call this SQL, here is an example for the deletion :
$this->admin->insertLogs($idCommentaire);
$this->admin->suppressCom($idCommentaire);
I've created a new column ENUM from MySql ("deleted" "modified") but can't figure out how can I update this Logs table with the datas on it.
Here is the SQL I'm thinking about :
UPDATE logs SET type =("modified"OR"deleted") WHERE com_id = 70;
Note that it's not a good coding, just what I want to do in my mind.
I'm talking about plain MySQL here, if it's possible to combine it all in one request.
Otherwise I would set up 1 more request, 1 for each, but I don't know if it's really clean to do so.
What's your advices and thoughts about it ?
Thanks you all.
Your logic isn't too bad. However, I'll note a couple of things.
TYPE is a reserved word in MySQL and probably most RDBMSs. Pick
another name for your column that indicates if a post has been
modified or deleted.
There is at least one more state for a post; it's approved, or
published, or 'okay', or whatever you'd like to call it. So if you
create an ENUM field called
SomethingOtherThanTypeThatStillMeansType, or foo or
post_status or whatever, include fields for all potential states
your data may have, including deleted, modified, posted, not_yet_posted, edited, or whatever you think the system may support at the time of some future feature update.
You might consider using an INT type for your status field. I'm
thinking that might be a tad faster than an ENUM.

Mysqli add numeric value with concat?

I need to update a the employee hours column with the current numeric value that is already existed in the database.
$mysqli->query("UPDATE `".MYDATABASE."`.`".MYTABLE."`
SET employeeHours='".$employeeHours."'
WHERE sessionID='".session_id()."'");
This like is working properly but needless to say that it's overwriting the old value.
My goal is to add the current $employeeHours to the existed value in the database.
I assume that it's done with concat but I'm not sure about the syntax.
Small tweak needed here...
I couldn't believe that it would be so ridiculously simple :
$mysqli->query("UPDATE `".MYDATABASE."`.`".MYTABLE."` SET employeeHours = employeeHours + '".$employeeHours."' WHERE sessionID='".session_id()."'");
Thank you #castis!

Update view count, most reliable way

Hello again Stackoverflow!
I'm currently working on custom forumsoftware and one of the things you like to see on a forum is a viewcounter.
All the approaches for a viewcounter that I found would just select the topic from the database, retrieve the number from a "views" column, add one and update it.
But here's my thought: If, lets say 400, people at the exact same time open a topic, the MySQL database probably won´t count all views because it takes time for the queries to complete, and so the last person (of the 400) might overwrites the first persons (of the 400) view.
Ofcourse one could argue that on a normal site this is never going to happen, but if you have ~7 people opening that topic at the exact same second and the server is struggleing at that moment, you could have the same problem.
Is there any other good approach to count views?
EDIT
Woah, could the one who voted down specify why?
I ment by "Retrieving the number of views and adding one" that I would use SELECT to retrieve the number, add one using PHP (note the tags) and updating it using UPDATE. I had no idea of the other methods specified below, that's why I asked.
If, lets say 400, people at the exact same time open a topic, the MySQL database apparently would count all the views because this is exactly what databases were invented for.
All the approaches for a viewcounter that you have found are wrong. To update a field you don't need to retrieve it, but just already update:
UPDATE forum SET views + 1 WHERE id = ?
So something like that will work:
UPDATE tbl SET cnt = cnt+1 WHERE ...
UPDATE is guaranteed to be atomic. That means no one will be able to alter cnt between the time it is read and the time it is replaced. If you have several concurrent UPDATE for the same row (InnoDB) or table (MyISAM) they have to wait their turn to update the date.
See Is incrementing a field in MySQL atomic?
and http://dev.mysql.com/doc/refman/5.1/en/ansi-diff-transactions.html

Find table from querying column name in oracle SQL developer

I want to query a database for a column name to find the table without knowing the table name (there are a huge number of tables)
I am working with a huge database at the moment and trying to find where, based on CFML code and the URL of the problematic page, a website is retrieving information from. I am new to ColdFusion however I can see that the URL contains a few ID references with column names. Some I have been able to find easily and others, I have no idea as the column names are quite vague e.g. 'NTASKID'.
My plan is to try to query the database using the column name but Google has presented me queries which require knowing the table name which I do not have. I guess those examples may have been more useful for denormalised tables(?).
If someone knows such a query it would be great. Additionally, could someone please comment on whether I am going down the right avenue of investigation here?
The query that worked was
SELECT * FROM ALL_TAB_COLUMNS
WHERE COLUMN_NAME LIKE '%TASK%'
AND owner = 'database_name';
It was the 'owner' part I did not previously know about. Everyone who answered certainly opened avenues for further Googling.
Cheers
If you need to find table name then 'juergen d' answered your question. If you nee to find column names then use user_tab_columns/all_tab_columns to select column names where table='YOUR_TABLE' - must be in upper case as well as column names.
The IDE itself has a feature for this, View > Find DB Obect
here's a 20 second video showing it, in action

Categories