I have been building a simple message board script, and have started writing a script named delete.php, where the user can input his/her password to delete the message. The message is stored with 4 values: id, name, password, timestamp, message.
The problem I am having is the DELETE query I am using will not completely remove the record. It will remove the name and message fields, but the row still exists with id, timestamp and password. So on my messageboard, rather than the message being deleted, theres a blank message with a timestamp.
I can delete the entry in PHPMyAdmin, but it won't work from my PHP script.
$db_connection->query("DELETE FROM 'messages' WHERE 'id' = ".$m_id.";")
or die($db_connection->error);
$m_id stores the ID number of the message.
No errors are returned, and I cannot access the Apache error log.
It may well be the ";" which is hampering your query, at the end of your statement here:
("DELETE FROM 'messages' WHERE 'id' = ".$m_id.";")
And as noted in the comment section, table names do not need quotes around them
A typical DELETE statement should be composed of a simple query like this:
mysql_query("DELETE FROM messages WHERE id='$m_id'") or die(mysql_error());
Although, using mysql_ function would be a very bad idea, since they are deprecated/not maintaned. In which case, you should learn PDO / mysqli
Try:
$db_connection->query('DELETE FROM messages WHERE id = ' . $m_id ) or die($db_connection->error);
If it doesn't work you can do 2 things:
1) Look at Apache's error log.
2) When you delete the row in PhpMyAdmin it often shows you the query used.
I looked at the screenshot you provided in the comments, and one possibility is that the existing record really is deleted, but a new one is added by a different piece of code. Without seeing all of your code, I can't tell if this is truly the case. It's something to look for, of course, in addition to making sure you don't have any triggers. Another possibility is that your delete statement isn't actually running at all, but another piece of code is updating that record and setting some of the columns to NULL/blank.
Related
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.
I have a hard time migrating a WebApp from a Unix/Apache/MySQL System to Win2012/Apache/MSSQL. First I installed the sqlsrv-stuff you need and the connection works.
BUT:
update queries cause error mesages like
A Database Error Occurred
Error Number: 42000/8102
[Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Die
id-Identitätsspalte kann nicht aktualisiert werden." The last part
basically means "The ID-identy column may not be updated."
The generated update-query looks like this:
UPDATE "dbo"."table" SET "id" = 1, "someStuff" = 5 WHERE "id" = 1
My models use statements like:
$data = array (
'someStuff' => (int) $stuff
);
$this->db->update('table',$data,"id = ".$itemID);
I understand the message as the statement contains a SET "id" which is obviously irrelevant as the id-field is an auto-increment thing generated in mssql - and as you see, I am not including it in my model. How do I get Codeigniter to reduce the UPDATE-statement to not contain primary keys? Or is there another easy way to resolve this?
If it helps, I might as well modify Codeigniter to check if the internally generated query contains an id field in order to skip these, as they are always auto-incremented primary keys, but my attempts to do so weren't successful.
If id is an auto-increment field, don't include it in the Codeigniter Insert/Update query. It should be added automatically. Just Insert/Update the other values on the DB
Rem: Auto-increment attribute is set on the Database level not on the Codeigniter.
As I found out, someone made undocumented last-minute changes during the migration and found out that the data-array did not contain the id - and for a reason I'll never understand he thought it would be a great idea to put them in.
Sorry sorry for the confusion!
Lessons learned:
CI works fine even with SQLSRV,
I'll have to make sure that the code I create is uploaded as I wanted it to be.
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 have a small PHP function on my website which basically does 3 things:
check if user is logged in
if yes, check if he has the right to do this action (DB Select)
if yes, do the related action (DB Insert/Update)
If I have several users connected at the same time on my website that try to access this specific function, is there any possibility of concurrency problem, like we can have in Java for example? I've seen some examples about semaphore or native PHP synchronization, but is it relevant for this case?
My PHP code is below:
if ( user is logged ) {
sql execution : "SELECT....."
if(sql select give no results){
sql execution : "INSERT....."
}else if(sql select give 1 result){
if(selected column from result is >= 1){
sql execution : "UPDATE....."
}
}else{
nothing here....
}
}else{
nothing important here...
}
Each user who accesses your website is running a dedicated PHP process. So, you do not need semaphores or anything like that. Taking care of the simultaneous access issues is your database's problem.
Not in PHP. But you might have users inserting or updating the same content.
You have to make shure this does not happen.
So if you have them update their user profile only the user can access. No collision will occur.
BUT if they are editing content like in a Content-Management System... they can overwrite each others edits. Then you have to implement some locking mechanism.
For example(there are a lot of ways...) if you write an update on the content keeping the current time and user.
Then the user has a lock on the content for maybe 10 min. You should show the (in this case) 10 min countdown in the frontend to the user. And a cancel button to unlock the content and ... you probably get the idea
If another person tries to load the content in those 10 min .. it gets an error. "user xy is already... lock expires at xx:xx"
Hope this helps.
In general, it is not safe to decide whether to INSERT or UPDATE based on a SELECT result, because a concurrent PHP process can INSERT the row after you executed your SELECT and saw no row in the table.
There are two solutions. Solution number one is to use REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. These two query types are "atomic" from perspective of your script, and solve most cases. REPLACE tries to insert the row, but if it hits a duplicate key it replaces the conflicting existing row with the values you provide, INSERT ... ON DUPLICATE KEY UPDATE is a little bit more sophisticated, but is used in a similar situations. See the documentation here:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
http://dev.mysql.com/doc/refman/5.0/en/replace.html
For example, if you have a table product_descriptions, and want to insert a product with ID = 5 and a certain description, but if a product with ID 5 already exists, you want to update the description, then you can just execute the following query (assuming there's a UNIQUE or PRIMARY key on ID):
REPLACE INTO product_description (ID, description) VALUES(5, 'some description')
It will insert a new row with ID 5 if it does not exist yet, or will update the existing row with ID 5 if it already exists, which is probably exactly what you want.
If it is not, then approach number two is to use locking, like so:
query('LOCK TABLE users WRITE')
if (num_rows('SELECT * FROM users WHERE ...')) {
query('UPDATE users ...');
}
else {
query('INSERT INTO users ...');
}
query('UNLOCK TABLES')
I trying to add +1 in a column after select but its not working, what I want is, when I make a search, the scripts adds +1 in a column to track how much searches I did.
Heres how it is now
$QUERY = "SELECT company FROM test WHERE number = '$number[0]' LIMIT 1";
And I want to add this
UPDATE users SET consultas=consultas+1 WHERE username = '$username'
If I add another $QUERY line the script breaks, any ideas ?
By nature, SELECT queries are for returning information from the database, not updating the database. To this end, triggers aren't even available for SELECT queries to react to the action. As such, if you want to increment a value, this must be done in a separate query, as an UPDATE query or possibly an INSERT ... ON DUPLICATE KEY UPDATE query if that better suits your needs.
You should execute those as two separate queries. Also, be very careful to ensure your data is properly escaped because it looks like you've forgotten to do that.
Be sure to check the result code of each as an error may occur at any time. If you use PDO there's a fairly robust error handling pattern you can follow.