0

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

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()函数。

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

4

2 回答 2

2

您可以使用TRIM

UPDATE table_name SET column = TRIM(LEADING 'some string' FROM 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'
于 2013-02-27T11:03:35.433 回答
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);
于 2017-03-15T18:34:25.753 回答