I'm trying to append a string to an existing record in a MySQL Database:
UPDATE `db`.`tbl` SET field1 = IFNULL(field1, '') + ',' + '12/15/16: $50' WHERE field2 = 'xyz'
In MySQL, + is exactly what it suggests: addition. You are getting an error on arithmetic presumably because the strings are not converted to a number (fortunately -- otherwise you would silently get the wrong answer).
So, try this:
UPDATE `db`.`tbl`
SET field1 = CONCAT(COALESCE(field1, ''), ',', '12/15/16: $50')
WHERE field2 = 'xyz';
Or, if you don't want the comma if field1 is NULL:
UPDATE `db`.`tbl`
SET field1 = CONCAT(COALESCE(CONCAT(field1, ','), ''), '12/15/16: $50')
WHERE field2 = 'xyz';
to append in MySQL, use concat not + eg
select concat('something', 'something_else');
returns
somethingsomething_else
you can also use concat_ws (with separator)
select concat_ws('#','something', 'something_else')
returns
something#something_else
Related
I am using UPDATE to insert simple text into a table where the field is MEDIUMTEXT (nullable field).
It is strange that it does not work when the field is null initially. If I manually enter at least a one character/space, then it's working.
I want to append the new text into existing text in the field.
UPDATE pen SET
PEN_STATUS = #PenStat,
PEN_STATUS_CHANGE_REASON = CONCAT(PEN_STATUS_CHANGE_REASON,'\n',ChangeDate,':',EmployeeID,':',ChangeReason)
WHERE PEN_ID = PenID;
Why is this?
CONCAT does not handle NULL values. As explained in the MySQL manual:
CONCAT() returns NULL if any argument is NULL.
You want to use COALESCE to handle that use case, like :
UPDATE pen SET
PEN_STATUS = #PenStat,
PEN_STATUS_CHANGE_REASON = CONCAT(
COALESCE(PEN_STATUS_CHANGE_REASON, ''),
'\n',
ChangeDate,
':',
EmployeeID,
':',
ChangeReason
)
WHERE PEN_ID = PenID;
Presumably, because something is NULL. Try using CONCAT_WS() instead:
UPDATE pen
SET PEN_STATUS = #PenStat,
PEN_STATUS_CHANGE_REASON = CONCAT_WS('\n',
PEN_STATUS_CHANGE_REASON,
CONCAT_WS(':', ChangeDate, EmployeeID, ChangeReason
)
)
WHERE PEN_ID = PenID;
CONCAT_WS() ignores NULL arguments. Plus, the separator only needs to be listed once.
I have a sybase query that is structured like this:
SELECT
case
when isnull(a,'') <> '' then a
else convert(varchar(20), b)
end
FROM table_name
WHERE b=123
It used to return the results of the 'case' in a column named 'converted'. It now returns the results of the 'case' in a column with an empty string name ''.
How could this be? Could there be some database configuration that defaults the results of a 'case' with no name?
(I've fixed the broken query by adding " as computed" after 'end' but now I'd like to know how it used to return as 'computed' before I added the fix?)
Is this what you want?
SELECT (case when isnull(a, '') <> '' then a
else convert(varchar(20), b)
end) as converted
-------------^
FROM table_name
WHERE b = 123;
By the way, you could write the select more succinctly as:
SELECT coalesce(nullif(a, ''), b) as converted
I have a field with this value:
TEST:ATEST:TESTA
And I want to replace "TEST" with "NEW", I have tried this query:
UPDATE `table` SET `field` = REPLACE(`field`, 'TEST', 'NEW') WHERE `field` REGEXP 'TEST';
The result was:
NEW:ANEW:NEWA
Q: How could I do the replacement query so the result would be like this:
NEW:ATEST:TESTA
It is a bit of a pain, but you can do it this way:
UPDATE `table`
SET field = substr(REPLACE(concat(':', field, ':'), ':TEST:', ':NEW:'),
2, length(REPLACE(concat(':', field, ':'), ':TEST:', ':NEW:')) - 2)
WHERE concat(':', field, ':') LIKE '%:TEST:%';
I prefer LIKE to REGEXP because there is the hope of being able to use an index. That is not a possibility in this case, but there is the hope.
This is delimiting the values with colons at the beginning and the end, and only replacing fully delimited values. The trick is to then remove the additional colons.
You can try http://sqlfiddle.com/#!9/4e66b/3
so the update query is (if table name = table1, field name = field1, and there is unique column id):
UPDATE `table1`
INNER JOIN
(SELECT id,
#set_idx:=FIND_IN_SET('TEST',REPLACE(field1,':',',')),
#set_size:=LENGTH(field1)-LENGTH(REPLACE(field1,':',''))+1,
CASE
WHEN #set_idx=1 THEN CONCAT('NEW',SUBSTRING(field1, 4))
WHEN #set_idx>1 THEN CONCAT(SUBSTRING_INDEX(field1, ':',#set_idx-1),':NEW', IF(#set_size>#set_idx,CONCAT(':',SUBSTRING_INDEX(field1, ':',-(#set_size-#set_idx))),''))
END as new
FROM table1
WHERE `field1` REGEXP '(^TEST$)|(^TEST:)|(:TEST$)|(:TEST:)'
) t
ON t.id = table1.id
SET table1.field1 = t.new;
I want to generate .sql file with the sql query output . I am doing this with concat statement in sql . I am using case statement in some queries this will be the problem for me.
select concat('insert into x values(',CASE a when B then 'Book' else 'NONE' end , ') on duplicate key update B = values(B)') from author;
select 'insert into x values('+CASE a when B then 'Book' else 'NONE' end +') on duplicate key update B = values(B)' from author;
It also not works because in mysql + used for adding only numbers not for strings .
Is there any way for doing this?.
The problem with the first version is the quotes of things within the string. For instance, you want your string to contain "'Book'"
select concat('insert into x values(',
(CASE a when 'B' then '''Book''' else '''NONE''' end) ,
') on duplicate key update B = values(''B'')'
)
from author;
I think this quotes al the strings as they should be. I'm guess column A is a character that should be compared to 'B' and not to column B.
I'm don't have a lot of knowledge of MySql (or SQL in general) so sorry for the noobness.
I'm trying to update a bunch of String entries this way:
Lets say we have this:
commands.firm.pm.Stuff
Well I want to convert that into:
commands.firm.pm.print.Stuff
Meaning, Add the .print after pm, before "Stuff" (where Stuff can be any Alphanumerical String).
How would I do this with a MySql Query? I'm sure REGEXP has to be used, but I'm not sure how to go about it.
Thanks
Try something like this. It finds the last period and inserts your string there:
select insert(s, length(s) - instr(reverse(s), '.') + 1, 0, '.print')
from (
select 'commands.firm.pm.Stuff' as s
) a
To update:
update MyTable
set MyColumn = insert(MyColumn, length(MyColumn) - instr(reverse(MyColumn), '.') + 1, 0, '.print')
where MyColumn like 'commands.firm.pm.%'
Perhaps use a str_replace to replace commands.firm.pm to commands.firm.pm.print
$original_str = "commands.firm.pm.15hhkl15k0fak1";
str_replace("commands.firm.pm", "commands.firm.pm.print", $original_str);
should output: commands.firm.pm.print.15hhkl15k0fak1
then update your table with the new value...How to do it all in one query (get column value and do the update), I do not know. All I can think of is you getting the column value in one query, doing the replacement above, and then updating the column with the new value in a second query.
To update rows that end in '.Stuff' only:
UPDATE TableX
SET Column = CONCAT( LEFT( CHAR_LENGTH(Column) - CHAR_LENGTH('.Stuff') )
, '.print'
, '.Stuff'
)
WHERE Column LIKE '%.Stuff'
To update all rows - by appending .print just before the last dot .:
UPDATE TableX
SET Column = CONCAT( LEFT( CHAR_LENGTH(Column)
- CHAR_LENGTH(SUBSTRING_INDEX(Column, '.', -1))
)
, 'print.'
, SUBSTRING_INDEX(Column, '.', -1)
)
WHERE Column LIKE '%.%'