Is there a way in MySQL to insert a condition based on which the entire UPDATE query will be executed? I know that you can use IF or CASE within the query itself to insert different values, but I'm talking about this scenario:
IF ( condition is true ) UPDATE ...
Let's say I wanted to validate data and execute the UPDATE based on result (I know it's a bad idea and data validation should be done scripting wise, I'm just reviewing the theoretical possibilities). Like here below where I test a value against regexp to check if it's numerical value:
UPDATE executed:
IF ( "12345" REGEXP "[0-9]+" ) UPDATE table SET numdata = "12345" WHERE...;
UPDATE not executed:
IF ( "a1234" REGEXP "[0-9]+" ) UPDATE table SET numdata = "a1234" WHERE...;
Thanks,
Prez
Just put the REGEXP in your WHERE clause:
DECLARE mynumdata varchar(10) = "a1234";
UPDATE table SET numdata = mynumdata
WHERE #numdata REGEXP "[0-9]+"
AND <other update conditions>;
One way to do this would be to add the condition to the WHERE clause.
So if you originally had
UPDATE table SET numdata = "a1234" WHERE id=1
you could write this as
UPDATE table SET numdata = "a1234" WHERE id=1 AND "1234" REGEXP "[0-9]+"
Related
I'm trying to update a table, with the IN function and a variable.
The content of the variable is a sub-query that returns the expected values aka ID for each STRING. When I copy/paste the values in the update, everything is fine.
USE `DB1`;
SET SQL_SAFE_UPDATES = 0;
SET #VAR1 = "STRING1,STRING2,STRING3,STRING4";
SET #VAR2 = (SELECT GROUP_CONCAT(`id`) FROM `tbl_A` WHERE FIND_IN_SET(`description`, #VAR1) AND `fieldtype` = '');
UPDATE `tbl_A`
SET `idaccount` = 2
WHERE `id` IN (#VAR2);
SET SQL_SAFE_UPDATES = 1;
So why when I use the variable, it updates only the first row?
The variable #VAR2 is a scalar variable, and can't store a result set. To do that, you would need a table variable, which MySQL does not directly support (note that other databases, such as SQL Server, do support them).
But, you may inline the subquery and it should work:
SET #VAR1 = "STRING1,STRING2,STRING3,STRING4";
UPDATE tbl_A
SET idaccount = 2
WHERE id IN (SELECT id FROM (
SELECT id FROM tbl_A
WHERE FIND_IN_SET(description, #VAR1) AND fieldtype = ''
)x );
Note that the subquery following the IN clause of the update is wrapped twice, to avoid the problem of trying to reference the same table which is being updated. This trick actually materializes the subquery, leaving it independent of what happens during the update.
In MySQL, I have a comma delimited list in the following format -
'id,text,id,text,id,text,etc...'
Example -
'1001,TextFor1001,1002,TextFor1002,1003,TextFor1003,etc...'
I need to update a SQL table like this -
UPDATE mytable
SET mytable.textfor = 'TextFor1001'
WHERE mytable.id = 1001;
How can I loop through the list without having to create an UPDATE statement for each entry?
EDIT: TO EXPLAIN MY QUESTION FURTHER -
I want to read through a string that looks like this-
'1001,TextFor1001,1002,TextFor1002,1003,TextFor1003,etc...'
And perform the equivalent of having multiple update statments like this -
UPDATE mytable
SET mytable.textfor = 'TextFor1001'
WHERE mytable.id = 1001;
UPDATE mytable
SET mytable.textfor = 'TextFor1002'
WHERE mytable.id = 1002;
UPDATE mytable
SET mytable.textfor = 'TextFor1003'
WHERE mytable.id = 1003;
etc...
Is there some kind of loop I can create that can read through the string, search for the id in a table, then update the record with the corresponding text value?
The basic syntax of UPDATE query with WHERE clause is as follows:
UPDATE table_name
SET column1 = value1, column2 = value2...., columnN = valueN
WHERE [condition];
You can combine N number of conditions using AND or OR operators
I want to do all these update in one statement.
update table set ts=ts_1 where id=1
update table set ts=ts_2 where id=2
...
update table set ts=ts_n where id=n
Is it?
Use this:
UPDATE `table` SET `ts`=CONCAT('ts_', `id`);
Yes you can but that would require a table (if only virtual/temporary), where you's store the id + ts value pairs, and then run an UPDATE with the FROM syntax.
Assuming tmpList is a table with an id and a ts_value column, filled with the pairs of id value, ts value you wish to apply.
UPDATE table, tmpList
SET table.ts = tmpList.ts_value
WHERE table.id = tmpList.id
-- AND table.id IN (1, 2, 3, .. n)
-- above "AND" is only needed if somehow you wish to limit it, i.e
-- if tmpTbl has more idsthan you wish to update
A possibly table-less (but similar) approach would involve a CASE statement, as in:
UPDATE table
SET ts = CASE id
WHEN 1 THEN 'ts_1'
WHEN 2 THEN 'ts_2'
-- ..
WHEN n THEN 'ts_n'
END
WHERE id in (1, 2, ... n) -- here this is necessary I believe
Well, without knowing what data, I'm not sure whether the answer is yes or no.
It certainly is possible to update multiple rows at once:
update table table1 set field1='value' where field2='bar'
This will update every row in table2 whose field2 value is 'bar'.
update table1 set field1='value' where field2 in (1, 2, 3, 4)
This will update every row in the table whose field2 value is 1, 2, 3 or 4.
update table1 set field1='value' where field2 > 5
This will update every row in the table whose field2 value is greater than 5.
update table1 set field1=concat('value', id)
This will update every row in the table, setting the field1 value to 'value' plus the value of that row's id field.
You could do it with a case statement, but it wouldn't be pretty:
UPDATE table
SET ts = CASE id WHEN 1 THEN ts_1 WHEN 2 THEN ts_2 ... WHEN n THEN ts_n END
I think that you should expand the context of the problem. Why do you want/need all the updates to be done in one statement? What benefit does that give you? Perhaps there's another way to get that benefit.
Presumably you are interacting with sql via some code, so certainly you can simply make sure that the three updates all happen atomically by creating a function that performs all three of the updates.
e.g. pseudocode:
function update_all_three(val){
// all the updates in one function
}
The difference between a single function update and some kind of update that performs multiple updates at once is probably not a very useful distinction.
generate the statements:
select concat('update table set ts = ts_', id, ' where id = ', id, '; ')
from table
or generate the case conditions, then connect it to your update statement:
select concat('when ', id, ' then ts_', id) from table
You can use INSERT ... ON DUPLICATE KEY UPDATE. See this quesion: Multiple Updates in MySQL
ts_1, ts_2, ts_3, etc. are different fields on the same table? There's no way to do that with a single statement.
I need to replace more than 20 000 names with new names i created given the CodeID.
For example: I must update all rows that contain "dog" (which has a CodeID of 1) with "cat", and update all rows that contain "horse" (which has a CodeID of 2) with "bird", etc.
1st SQL statement: UPDATE animalTable SET cDescription = "cat" WHERE CodeID = 1
2nd SQL statement: UPDATE animalTable SET cDescription = "bird" WHERE CodeID = 2
These statements work, but i need a faster way to do this because i have over 20 000 names.
Thank you in advance.
Thats the fastest way you can do it.
Or do you want update all records in a single command?
you can do a update with a join (Fixed Syntax... Havent used this one in a while)
UPDATE animalTable
INNER JOIN CodeTable ON animalTable.CodeID = CodeTable.ID
SET animalTable.cDescription = CodeTable.Description_1;
Another option is to split the updates into smaller batches, this will reduce the time the table is locked... But the total time of the updates will take longer (Its just an improvement of precieved Performance) You can do that by updating only certain ID ranges in each batch.
Also you could have that data in a separate table. Since the data is not normalized. Move it away so its more normalized.
You might want to create a temporary table that holds the translation values and update based on that.
For example:
create table #TRANSLATIONS
(
from varchar(32),
to varchar(32)
)
Then, insert the translation values:
insert into #TRANSLATIONS (from,to) values ('cat','dog')
Finally, update based on that:
update MYTABLE
set myvalue = t.to
where myvalue = t.from
from MYTABLE m,
#TRANSLATIONS t
(Untested, off the top of my head).
You could use a CASE statement to update it:
UPDATE animaltable SET cDescription = CASE codeID WHEN 1 THEN 'cat' WHEN 2 THEN 'bird'.... END
Supposind you have a file like this:
1,cat
2,bird
...
I would write a script which reads that file and executes an update for each row.
In PHP:
$f = fopen("file.csv","r")
while($row = fgetcsv($f, 1024)) {
$sql = "update animalTable set cDescription = '".$row[1]."' where CodeID = ".$row[0];
mysql_query($sql);
}
fclose($f);
What you could do to speed it up is to only update those records that don't already have the value you want to assign.
UPDATE animalTable SET cDescription = "cat" WHERE CodeID = 1 AND cDescription != "cat"
This approach makes the command only update those records that are not already 'cat'.
Disclaimer: I hate cats.
I need a SQL update statement for updating a particular field of all the rows with a string "test" to be added in the front of the existing value.
For example, if the existing value is "try" it should become "testtry".
You can use the CONCAT function to do that:
UPDATE tbl SET col=CONCAT('test',col);
If you want to get cleverer and only update columns which don't already have test prepended, try
UPDATE tbl SET col=CONCAT('test',col)
WHERE col NOT LIKE 'test%';
UPDATE tablename SET fieldname = CONCAT("test", fieldname) [WHERE ...]
Many string update functions in MySQL seems to be working like this:
If one argument is null, then concatenation or other functions return null too.
So, to update a field with null value, first set it to a non-null value, such as ''
For example:
update table set field='' where field is null;
update table set field=concat(field,' append');
That's a simple one
UPDATE YourTable SET YourColumn = CONCAT('prependedString', YourColumn);
UPDATE table_name SET Column1 = CONCAT('newtring', table_name.Column1) where 1
UPDATE table_name SET Column1 = CONCAT('newtring', table_name.Column2) where 1
UPDATE table_name SET Column1 = CONCAT('newtring', table_name.Column2, 'newtring2') where 1
We can concat same column or also other column of the table.