0

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
iTesTi
  • 3
  • 1

2 Answers2

0

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.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
0

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;
Alex
  • 16,739
  • 1
  • 28
  • 51