post_content 列に html コンテンツがあります。
A を検索して B に置き換えたいのですが、A が複数回出現する可能性があるため、レコードに最初に出現したときだけにします。
以下のクエリは、明らかに A のすべてのインスタンスを B に置き換えます。
UPDATE wp_posts SET post_content = REPLACE (post_content, 'A', 'B');
post_content 列に html コンテンツがあります。
A を検索して B に置き換えたいのですが、A が複数回出現する可能性があるため、レコードに最初に出現したときだけにします。
以下のクエリは、明らかに A のすべてのインスタンスを B に置き換えます。
UPDATE wp_posts SET post_content = REPLACE (post_content, 'A', 'B');
これは、実際に 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
または、関数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');
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;
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
注:ユーザー入力のように見えるため、セキュリティの問題に関しては本当に注意する必要があります。
この質問が出されてから数年が経過し、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 ;
gjreda のサンプルをもう少しシンプルにするには、次のようにします。
UPDATE wp_post
SET post_content =
CONCAT(
REPLACE(LEFT(post_content, 1), 'A', 'B'),
SUBSTRING(post_content, 2)
)
WHERE post_content LIKE 'A%';