13

post_content 列に html コンテンツがあります。

A を検索して B に置き換えたいのですが、A が複数回出現する可能性があるため、レコードに最初に出現したときだけにします。

以下のクエリは、明らかに A のすべてのインスタンスを B に置き換えます。

UPDATE wp_posts SET post_content = REPLACE (post_content, 'A', 'B');

4

9 に答える 9

15

これは、実際に MySQL で必要なものである必要があります。

UPDATE wp_post
SET post_content = CONCAT(REPLACE(LEFT(post_content, INSTR(post_content, 'A')), 'A', 'B'), SUBSTRING(post_content, INSTR(post_content, 'A') + 1));

私の以前の答えよりも少し複雑です - SUBSTRING と INSTR を使用して同じものを見つけるよりも、「A」の最初のインスタンスを (INSTR 関数を使用して) 見つけてから、LEFT を REPLACE と組み合わせて使用​​して、そのインスタンスだけを置き換える必要があります。 「A」を置き換えて、前の文字列と CONCAT します。

以下の私のテストを参照してください。

SET @string = 'this is A string with A replace and An Answer';
SELECT @string as actual_string
, CONCAT(REPLACE(LEFT(@string, INSTR(@string, 'A')), 'A', 'B'), SUBSTRING(@string, INSTR(@string, 'A') + 1)) as new_string;

プロデュース:

actual_string                                  new_string
---------------------------------------------  ---------------------------------------------
this is A string with A replace and An Answer  this is B string with A replace and An Answer
于 2012-08-25T16:07:55.633 に答える
12

または、関数LOCATE()INSERT()、およびCHAR_LENGTH()を次のように使用できます。

INSERT(originalvalue, LOCATE('A', originalvalue), CHAR_LENGTH('A'), 'B')

完全なクエリ:

UPDATE wp_posts
SET post_content = INSERT(originalvalue, LOCATE('A', originalvalue), CHAR_LENGTH('A'), 'B');
于 2012-08-25T17:58:46.713 に答える
2

https://dba.stackexchange.com/a/43919/200937を参照すると、別の解決策があります。

UPDATE wp_posts 
SET post_content = CONCAT( LEFT(post_content , INSTR(post_content , 'A') -1),
                           'B',
                           SUBSTRING(post_content, INSTR(post_content , 'A') +1))
WHERE INSTR(post_content , 'A') > 0;

たとえば、別の文字列がある場合は、上記を対応する文字列の長さにtesting変更する必要があります。この目的のために+1使用できます。LENGTH()ちなみに-1手付かずのまま。

例: 「testing」を「whatever」に置き換えます。

UPDATE wp_posts 
SET post_content = CONCAT( LEFT(post_content , INSTR(post_content , 'testing') -1),
                           'whatever',
                           SUBSTRING(post_content, INSTR(post_content , 'testing') + LENGTH("testing"))
WHERE INSTR(post_content , 'testing') > 0;


ちなみに、影響を受ける行数を確認するのに役立ちます。

SELECT COUNT(*)
FROM post_content 
WHERE INSTR(post_content, 'A') > 0;
于 2020-03-08T10:13:05.490 に答える
1

Oracle DB を使用している場合は、次のように記述できるはずです。

UPDATE wp_posts SET post_content = regexp_replace(post_content,'A','B',1,1)

詳細については、こちらを参照してください: http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions130.htm

post_content注:ユーザー入力のように見えるため、セキュリティの問題に関しては本当に注意する必要があります。

于 2012-08-25T16:07:22.970 に答える
0

この質問が出されてから数年が経過し、MySQL 8 ではREGEX_REPLACEが導入されました。

REGEXP_REPLACE(expr、pat、repl[、pos[、occurrence[、match_type]]])

パターン pat で指定された正規表現に一致する文字列 expr 内のオカレンスを置換文字列 repl に置き換え、結果の文字列を返します。expr、pat、または repl が NULL の場合、戻り値は NULL です。

REGEXP_REPLACE()は、次のオプションの引数を取ります。

pos : 検索を開始する expr 内の位置。省略した場合、デフォルトは 1 です
。occurrence : 置換する一致の出現。省略した場合、デフォルトは 0 です (これは、「出現箇所をすべて置き換える」ことを意味します)。
match_type : マッチングの実行方法を指定する文字列。意味は REGEXP_LIKE() で説明したとおりです。

したがって、ケースで正規表現を使用できると仮定します。

UPDATE wp_posts SET post_content = REGEXP_REPLACE (post_content, 'A', 'B', 1, 1);

残念ながら、MariaDB を使用している私たちにとっては、そのREGEXP_REPLACEフレーバーには発生パラメーターがありません。Luciano Seibelが提案したように、再利用可能な関数として便利に保存されたAndriy Mのソリューションの正規表現対応バージョンを次に示します。

DELIMITER //
DROP FUNCTION IF EXISTS replace_first //
CREATE FUNCTION `replace_first`(
    `i` TEXT,
    `s` TEXT,
    `r` TEXT
)
RETURNS text CHARSET utf8mb4
BEGIN
    SELECT REGEXP_INSTR(i, s) INTO @pos;
    IF @pos = 0 THEN RETURN i; END IF;
    RETURN INSERT(i, @pos, CHAR_LENGTH(REGEXP_SUBSTR(i, s)), r);
END;
//
DELIMITER ;
于 2019-07-23T15:07:35.567 に答える
-1

gjreda のサンプルをもう少しシンプルにするには、次のようにします。

UPDATE wp_post
    SET post_content =
            CONCAT(
                REPLACE(LEFT(post_content, 1), 'A', 'B'),
                SUBSTRING(post_content, 2)
            ) 
    WHERE post_content LIKE 'A%';
于 2014-11-12T09:29:27.533 に答える