MySQL只替换文本字段/列中的第一个匹配项

时间:2013-02-27 10:41:16

标签: mysql replace

我写了一个函数来替换MySQL Text colum中的第一个出现,但它有点复杂......

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

$length是字符串的长度,我们想要替换它。如果我们使用php它是strlen()函数,但在MySQL中它将是CHAR_LENGTH()函数。

您是否知道更换文本列中的第一个匹配项的更好方法?

2 个答案:

答案 0 :(得分:2)

您可以使用TRIM

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

假设'some string'在'column'内容的开头没有连续出现超过1次。

因此,如果包含列,它将起作用:

"some string foo some string"

但不适用于:

"some string some string foo some string"

编辑 - 添加了MySQL功能以简化流程

我看不到你正在使用的机制的替代方法,但是通过在MySQL中创建一个函数(如果你有权限)可以简化执行它:

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 ;

然后你可以使用:

来调用它
select replace_first('bar foo foo baz foo', 'foo');

结果:

'bar  foo baz'

答案 1 :(得分:0)

我创建的函数可以替换任何文本索引:

/************** 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);