2013-02-27 69 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); 
相關問題