简体   繁体   中英

MySQL replace only first occurence in text field/column

I wrote a function to replace first occurence in MySQL Text colum, but it's a little bit complicated...

UPDATE
  table_name
SET
  column=CONCAT(
           LEFT(column,LOCATE('some string', column)-1),
           CONCAT(substring(column, LOCATE('some string', column) + $length),
           'new string'))

Where $length is length of string, that we want to replace. If we use php it is strlen() function but in MySQL it would be CHAR_LENGTH() function.

Do you know better way to replace only first match in text columns ?

You could use TRIM :

UPDATE table_name SET column = TRIM(LEADING 'some string' FROM column);

assuming 'some string' does not have more than 1 consecutive occurrence at the start of the contents of 'column'.

So, it would work if column contained:

"some string foo some string"

but not for:

"some string some string foo some string"

Edit - Added MySQL function to simplify process

I can't see an alternative to the mechanism you are using, but executing it could be simplified by creating a function in MySQL (if you have the privilege):

delimiter $$

create function replace_first(
   p_text_to_search varchar(255),
   p_text_to_replace varchar(255)
)
returns varchar(255)
begin
   declare v_found_pos int(11);
   declare v_found_len int(11);
   declare v_text_with_replacement varchar(255);

   select locate(p_text_to_replace, p_text_to_search)
   into   v_found_pos;

   select char_length(p_text_to_replace)
   into   v_found_len;

   select concat(
            left(p_text_to_search, v_found_pos-1),
            mid(p_text_to_search, (v_found_pos + v_found_len))
          )
   into   v_text_with_replacement;

   return v_text_with_replacement;
end$$

delimiter ;

then you can call it using:

select replace_first('bar foo foo baz foo', 'foo');

result:

'bar  foo baz'

I have created function can replace any index of text:

/************** REPLACE_TEXT_OF_INDEX ***************/
DROP FUNCTION IF EXISTS REPLACE_TEXT_OF_INDEX;
DELIMITER $$
CREATE FUNCTION REPLACE_TEXT_OF_INDEX(_text  VARCHAR(3072), _subText VARCHAR(1024), _toReplaceText VARCHAR(1024), _index INT UNSIGNED)
RETURNS VARCHAR(3072)
BEGIN
    DECLARE _prefixText, _sufixText VARCHAR(3072);
    DECLARE _starIndex INT;
    DECLARE _loopIndex, _textIndex INT UNSIGNED DEFAULT 0;

    IF  _text IS NOT NULL AND LENGTH(_text) > 0 AND
        _subText IS NOT NULL AND LENGTH(_subText) > 0 AND
        _toReplaceText IS NOT NULL AND _index > 0 THEN

        WHILE _loopIndex < LENGTH(_text) AND _textIndex < _index DO
            SELECT LOCATE(_subText, _text, _loopIndex + 1) INTO _loopIndex;
            IF _loopIndex > 0 THEN
                SET _textIndex = _textIndex + 1;
            ELSE
                SET _loopIndex = LENGTH(_text) + 1;
            END IF;
        END WHILE;
        IF _textIndex = _index THEN    
            SELECT LOCATE(_subText, _text, _loopIndex) INTO _starIndex;
            SELECT SUBSTRING(_text, 1, _starIndex -1) INTO _prefixText;
            SELECT SUBSTRING(_text, _starIndex + LENGTH(_subText), LENGTH(_text)) INTO _sufixText;
            RETURN CONCAT(_prefixText, _toReplaceText, _sufixText);
        END IF;
    END IF;

    RETURN _text;
END;
$$
DELIMITER ;

SELECT REPLACE_TEXT_OF_INDEX('WORD1 WORD2 WORD3 WORD4 WORD5', 'WORD', '*',1);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM