Incrementing in MySQL - mysql

I try to increment a field in mysql but it seems that it is not really working for some reasons ...
That is the query I run in mysql query:
UPDATE profil_perso
SET profile_views = profile_views +1
WHERE id = 30537
In the status bar it says : 1 row affected by the last command. No resultset returned. But it didn't seemed to work. At first I thougth that it was simply because there were no rows at all. So then I ran this query:
SELECT *
FROM profil_perso
WHERE id = 30537
And found 1 row and the profile_views field is still at 0...
Any ideas of why this would be that way ?
[edit]
profile_views = 1 (set manually) at this moment and it still doesn't work.

Didn't you forget to commit a transaction when working with an InnoDB table?
UPDATE:
Since it's a MyISAM, I'll ask yet a couple of stupid questions:
Are you absolutely sure you're issuing UPDATE and SELECT against one database?
I once had a large farm of databases with identical schemata, and this used to be a problem when someone deleted something from the wrong database.
Aren't you using some kind of client caching on your client? What client are you using?
And try to REPAIR your table, this also may be the issue.

Just to verify - is profile_views zero, or null? If you add 1 to null, you still get null, so that could be your problem.
ETA:
So it isn't null. Next question would be, do you have autocommit on or, if not, did you issue a "commit"? Could be that it was updated, but your update never committed.

If it's null, won't increment.
UPDATE profil_perso
SET profile_views = IF(profile_views,profile_views+1,1)
WHERE id = 30537

Add some parens and a coalesce to see if that fixes it:
UPDATE profil_perso
SET profile_views = ( COALESCE(profile_views,0) + 1 )
WHERE id = 30537

Related

MySQL update returns 0 rows affected while select returns results

select * from t_circle
where status = 0 and author_phone = 13511111111
and id in (
1,
2,
3
)
;
returns 3 rows with status of 0.
But the following update query with same conditions returns 0 rows affected:
udpate t_circle set status = 2
where status = 0 and author_phone = 13511111111
and id in (
1,
2,
3
);
Is there a reason for this? I have tried start transaction and commit, but still 0 rows affected. Other questions' answers suggest to run select first and make sure the rows are changed since if new value == old value, it is considered affected. I have excluded these 2 possibilities.
Note: this issue is found in our production server(Yeah I know I shouldn't but I have to) with InnoDB engine. I could modify the contents in GUI client like DBeaver and click save and the changes take effect, but not with sql statements. I wonder if it has anything to do with my account authorization?
Resolved! It is because I misspelled UPDATE. When I use mysql> in command line, update with 'udpate' just gives Query OK, 0 rows affected. My mysql's version is 5.7
I know that there is something wrong with the user permission of your client
By comparing GUI generated sql queries when I change something in GUI and my own queries. I found out the reason is I misspelled update to udpate. Now I begin to wonder how could mysql not complain about syntax error and just returns with 0 rows affected?
Well, at least now I know what to do when something odd happens.

PROBLEM WITH - AUTO_INCREMENT VALUE IN TABLE_SCHEMA NOT UPDATING

SCENARIO
ALTER TABLE {TABLE NAME} AUTO_INCREMENT = 1;
INSERT INTO {TABLE NAME} ({COLUMN}) VALUES (1);
(this is only record in table after auto increment was updated)
SELECT AUTO_INCREMENT FROM information_schema.TABLES
WHERE TABLE_SCHEMA = {DATABASE NAME}
AND TABLE_NAME = {TABLE NAME};
the last select auto_increment is returning the old value before execution alter table in step 1) and I don't understand why and hot to fix it or maybe alter table in step 1) is not correct way to reset auto_increment.
THX
PS. I know a bit but not everything. I was researching this problem and didn't find satisfactory/explanatory answer.
The INFORMATION_SCHEMA doesn't update to reflect recent alterations. MySQL 8.0 changed it so it only updates once every 24 hours.
You can set this:
SET GLOBAL information_schema_stats_expiry=0;
That will make INFORMATION_SCHEMA update immediately, at the cost of some overhead on your system.
I had the issue where the information schema wasn't being immediately updated.
To fix this I ran:
SET PERSIST information_schema_stats_expiry = 0;
As using SET GLOBAL didn't work for me.
Hope this helps somebody else.
I guess you must set AUTO_INCREMENT = 1 not 0

Why EXISTS() always returns true?

Here is my query (used in a TRIGGER):
update user_details
set views_profile = views_profile + 1
where user_id = new.user_id and not exists (
SELECT 1
FROM views_profile vp
WHERE vp.user_id = new.user_id and vp.viewer_id = new.viewer_id
)
The TRIGGER:
As you can see, my query is an UPDATE statement and the problem is, it never happens. According to some tests, the problem is related to EXISTS. When I remove it, that UPDATE happens.
Anyway, why EXISTS is true all the time? Even when there isn't any row in views_profile table?
You are using a TRIGGER with AFTER INSERT so the new line is available on the UPDATE (and can be found on the EXISTS). You can change the time to BEFORE.

How to select and update a record at the same time in mySQL?

Is there any way to select a record and update it in a single query?
I tried this:
UPDATE arrc_Voucher
SET ActivatedDT = now()
WHERE (SELECT VoucherNbr, VoucherID
FROM arrc_Voucher
WHERE ActivatedDT IS NULL
AND BalanceInit IS NULL
AND TypeFlag = 'V'
LIMIT 1 )
which I hoped would run the select query and grab the first record that matches the where clause, the update the ActivatedDT field in that record, but I got the following error:
1241 - Operand should contain 1 column(s)
Any ideas?
How about:
UPDATE arrc_Voucher
SET ActivatedDT = NOW()
WHERE ActivatedDT IS NULL
AND BalanceInit IS NULL
AND TypeFlag = 'V'
LIMIT 1;
From the MySQL API documentation :
UPDATE returns the number of rows that were actually changed
You cannot select a row and update it at the same time, you will need to perform two queries to achieve it; fetch your record, then update it.
If you are worrying about concurrent processes accessing the same row through some kind of race condition (supposing your use case involve high traffic), you may consider other alternatives such as locking the table (note that other processes will need to recover--retry--if the table is locked while accessing it)
Or if you can create stored procedure, you may want to read this article or the MySQL API documentation.
But about 99% of the time, this is not necessary and the two queries will execute without any problem.

MYSQL Updating multiple fields from fields of another table

Scenario:
I have an application that has a config table which stores the config data for each website thats uses the application. I have added a couple of extra columns to the config table and rolled this out to all applications. I have since updated these new columns with data that needs to be the same on all the config tables.
How would I go about doing this?
My first thought would be to duplicate the table and do the following:
UPDATE `config` SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2` LEFT JOIN `tmp_config` ON (`tmp_config`.`tmp_id` = `config`.`id`)
Would this have the desired affect.
The following has worked for me (USING an INNER join and moving the SET to the end of the query:
UPDATE `config` INNER JOIN `tmp_config` ON (`tmp_config`.`id` = `config`.`id`)
SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2`
Thanks for all your help!
I don't quite understand all of your question. Where have you changed the config? I read your explanations as:
You have changed the schema for all applications
You have updated the applications' configurations elsewhere
See VolkerK's answer for the correct syntax for multi-table updates.
Which storage engine are you using? If it's InnoDb (or other engine that supports transactions), you should start a transaction before running the query. Then you can verify that the result is the desired one before you commit any changes:
Example:
mysql> START TRANSACTION;
mysql> SELECT * FROM Configs LIMIT 5; -- See what it looks like before
mysql> Run update query here
mysql> SELECT * FROM Configs LIMIT 5; -- Verify that the result is the expected one
mysql> COMMIT;
This should have the effect of updating new1 and new2 in config to the values of new1 and new2 in tmp_config where ever the ids from the two tables match (and null if there is no match in tmp_config).
I believe that's what you said you are trying to do.
From the MySql update reference:
You can also perform UPDATE operations
covering multiple tables. However, you
cannot use ORDER BY or LIMIT with a
multiple-table UPDATE. The
table_references clause lists the
tables involved in the join. Its
syntax is described in Section
12.2.8.1, “JOIN Syntax”. Here is an example:
UPDATE items,month SET
items.price=month.price WHERE
items.id=month.id;
In this case they're not using just the "JOIN" syntax, but the JOIN syntax should still be valid, you just need to do it prior to the SET clause.
It would look something like
UPDATE `config`
LEFT JOIN `tmp_config` ON (`tmp_config`.`tmp_id` = `config`.`id`)
SET `config`.`new1` = `tmp_config`.`new1`, `config`.`new2` = `tmp_config`.`new2`
you need to do like :
edit
CREATE TABLE newtable SELECT * FROM oldtable;
MySQL creates new columns for all elements in the SELECT. For example:
mysql> CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
-> PRIMARY KEY (a), KEY(b))
-> TYPE=MyISAM SELECT b,c FROM test2;
The multi-table update syntax doesn't allow a JOIN where you put it, see http://dev.mysql.com/doc/refman/5.0/en/update.html
UPDATE
config, tmp_config
SET
config.new1 = tmp_config.new1,
config.new2 = tmp_config.new2
WHERE
tmp_config.tmp_id = config.idshould do the trick (untested, no warranty ;-))