When updating a table in MySQL, for example:
Table user
user_id | user_name
1 John
2 Joseph
3 Juan
If I run the query
UPDATE `user` SET user_name = 'John' WHERE user_id = 1
Will MySQL write the same value again or ignore it since it's the same content?
As the MySQL manual for the UPDATE statement implies,
If you set a column to the value it currently has, MySQL notices this
and does not update it.
So, if you run this query, MySQL will understand that the value you're trying to apply is the same as the current one for the specified column, and it won't write anything to the database.
Related
I am porting a MSSQL stored procedure to MYSQL and i have a stored procedure that does this.
get the last value in a table by select Max.
add the new value to the table (along with other record
get the last value and store it in a variable for other processing
So far what i have the following
DECLARE lastSeq INT Default 0;
SELECT max(seq) INTO lastSeq from mytable;
Set newSeq = lastSeq + 1;
insert into mytable (seq, value1, value2, value3) values (newSeq, 1, 2, 3);
Unfortunately this is NOT thread safe, say if I select max(seq) and then a new record was added by other thread running a different query, by the time i reach insert, the value is already wrong.
In MSSQL I did this by locking the table during query of max(seq).
BUT
MYSQL does not allow locking of tables in stored procedure, so I cannot directly port the approach.
Havent had the luck to find solution while searching, maybe i am not putting the right keywords in search.
How can I do this in MYSQL thread safe inside stored procedure?
Update: I cannot use auto_increment for this column as this column is not unique and we allow duplicate, maybe my sample is wrong since i used "sequence" which should be auto increment, but in my real code, i use it for a different column that allows duplication.
example;
record id userid name seq status
1 1 adam 1 A
2 1 adam 2 C
3 2 Bob 1 C
In the above record, we have 2 records for Adam but only one valid set to "C" as current and "A" as archived or old value.
so my table has 2 valid record,
This is a bit long for a comment.
So change the data type to be auto_increment. There is no need to do re-implement this logic in a trigger, when the database basically does it for you.
If you are concerned about gaps, then just use row_number() over (order by seq) when you query the table.
I have a column in MySQL database that store the images names/IDs something like "523523525.jpg".
I want to update this column by adding the folder before the image name/ID to be like "101/523523525.jpg". I want to update specific records not all the column, for example update from record 1 to 1000 by adding "101/...." and records from 1001 to 2000 by adding "102/....".
Look for your ideas.
Add an id column.
ALTER TABLE your_table ADD
COLUMN id INT AUTO_INCREMENT
PRIMARY KEY FIRST;
use concat to update rows based on id
UPDATE your_table SET
Column=CONCAT("101/",column)
WHERE id BETWEEN 1 AND 1000;
for first 1 to 1000 to use LIMIT in update statement.
For next 1001-2000 you need to write anonymous block or procedure using cursor to update records.
How about using the CONCAT function? Assuming you have a seperate column for the id, you can execute an update query to add the path to the existing value.
UPDATE your_table SET path_col=CONCAT('101/', path_col) WHERE id between 1 AND 1000;
Hope it helps! Feel free to ask if you need to know anything.
I've looked over all of the related questions i've find, but couldn't get one which will answer mine.
i got a table like this:
id | name | age | active | ...... | ... |
where "id" is the primary key, and the ... meaning there are something like 30 columns.
the "active" column is of tinyint type.
My task:
Update ids 1,4,12,55,111 (those are just an example, it can be 1000 different id in total) with active = 1 in a single query.
I did:
UPDATE table SET active = 1 WHERE id IN (1,4,12,55,111)
its inside a transaction, cause i'm updating something else in this process.
the engine is InnoDB
My problem:
Someone told me that doing such a query is equivalent to 5 queries at execution, cause the IN will translate to the a given number of OR, and run them one after another.
eventually, instead of 1 i get N which is the number in the IN.
he suggests to create a temp table, insert all the new values in it, and then update by join.
Does he right? both of the equivalency and performance.
What do you suggest? i've thought INSERT INTO .. ON DUPLICATE UPDATE will help but i don't have all the data for the row, only it id, and that i want to set active = 1 on it.
Maybe this query is better?
UPDATE table SET
active = CASE
WHEN id='1' THEN '1'
WHEN id='4' THEN '1'
WHEN id='12' THEN '1'
WHEN id='55' THEN '1'
WHEN id='111' THEN '1'
ELSE active END
WHERE campaign_id > 0; //otherwise it throws an error about updating without where clause in safe mode, and i don't know if i could toggle safe mode off.
Thanks.
It's the other way around. OR can sometimes be turned into IN. IN is then efficiently executed, especially if there is an index on the column. If you have 1000 entries in the IN, it will do 1000 probes into the table based on id.
If you are running a new enough version of MySQL, I think you can do EXPLAIN EXTENDED UPDATE ...OR...; SHOW WARNINGS; to see this conversion;
The UPDATE CASE... will probably tediously check each and every row.
It would probably be better on other users of the system if you broke the UPDATE up into multiple UPDATEs, each having 100-1000 rows. More on chunking .
Where did you get the ids in the first place? If it was via a SELECT, then perhaps it would be practical to combine it with the UPDATE to make it one step instead of two.
I think below is better because it uses primary key.
UPDATE table SET active = 1 WHERE id<=5
Would this SQL query work for an SQL database?
UPDATE tableName SET colName1='value' WHERE colName2='Id_1' OR colName2='Id_2'
Basically, can I update the same column for multiple entries by checking against another column twice?
For example(as shown above), set colName1 to a value for 2 seperate entries which are identified by two different IDs
Yes that would work but you can make it more efficient like this:
UPDATE tableName SET colName1='value' WHERE colName2 in('Id_1','Id_2')
I have a database which can be accessed by multiple users. Is there any way I can set the tables such that whenever somebody enters a new record or modifies a record, his/her username and the date entered is stored into 2 columns in the same table as the record itself. The table would look like this:
Id | Name | Username | Date Entered | Date Modified
1 | Cat | john | 1999-05-05 | 1996-06-06
I am using a GUI which is phpMyAdmin.
Thanks!
You can set a column to not allow null values, either when you create the table using NOT NULL after the data type declaration. Otherwise, you use an ALTER TABLE statements to change a column if they already exist, or you are adding the column to an existing table.
That will stop someone from adding a record, but not update. If you have a separate table of users to reference, you would use a foreign key relationship to make sure that if the user column is populated, it will be done with a valid user.
DEFAULT constraints can be used to set the value of the date fields if a value is not provided.
ALTER TABLE x
ADD USER VARCHAR(45) NOT NULL
ALTER TABLE x
ADD DATE_ENTERED DATE NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
ALTER TABLE x
ADD DATE_ENTERED DATE NOT NULL DEFAULT ON UPDATE CURRENT_TIMESTAMP
First of all, you may want to spend some time thinking about the best way to design an audit mechanism, because adding two columns to every table in your DB is probably not optimal.
Having said that, what you are looking for to do what you described is a trigger. This is a piece of SQL that will execute every time a specified operation is invoked. A rough example for your case:
create trigger audit
after insert on "table_name"
insert (user, time) into "table_name"
I don't remember the precise mysql syntax, but that's a rough example of what you need. Please ask a follow-up question if that isn't clear.