2013-02-27 82 views
0

我写了一个函数来替换第一次出现在MySQL文本科拉姆,但它是一个有点复杂......MySQL的替换文本字段/只一次出现列

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

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

+0

我已经更新了我的答案 - 没有完全不同,但它可能有帮助。 – Raad 2013-02-27 13:08:08

回答

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' 
+0

但是当你想删除中间的字符串,那么这不会工作 – instead 2013-02-27 12:00:31

+0

@instead - 是的,这是正确的;但是你要求只取代首发,你不是吗? =) – Raad 2013-02-27 12:03:19

+0

是的,第一次出现但id并不意味着它是在字符串开始处的第一次出现;) – instead 2013-02-27 12:23:28

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); 
相关问题