SQLで文字列置換--WordPressの記事を一括置換

WordPressの記事などでclassの仕様を変更して、記事中のclass表記をすべてを書き換えたいとき、1つ1つの記事を編集していくというのは気が遠くなってしまう。記事全体にSQL文を発行して、文字列置換をしてしまいたいと思う。

WordPressの投稿記事は通常wp_postsの中にある、post_contentに格納されている。

# mysql -p -u root

mysql> use wordpress
mysql> desc wp_posts;
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field                 | Type                | Null | Key | Default             | Extra          |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID                    | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| post_author           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| post_date             | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_date_gmt         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content          | longtext            | NO   |     | NULL                |                |
| post_title            | text                | NO   |     | NULL                |                |
| post_excerpt          | text                | NO   |     | NULL                |                |
| post_status           | varchar(20)         | NO   |     | publish             |                |
| comment_status        | varchar(20)         | NO   |     | open                |                |
| ping_status           | varchar(20)         | NO   |     | open                |                |
| post_password         | varchar(20)         | NO   |     |                     |                |
| post_name             | varchar(200)        | NO   | MUL |                     |                |
| to_ping               | text                | NO   |     | NULL                |                |
| pinged                | text                | NO   |     | NULL                |                |
| post_modified         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_modified_gmt     | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content_filtered | longtext            | NO   |     | NULL                |                |
| post_parent           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| guid                  | varchar(255)        | NO   |     |                     |                |
| menu_order            | int(11)             | NO   |     | 0                   |                |
| post_type             | varchar(20)         | NO   | MUL | post                |                |
| post_mime_type        | varchar(100)        | NO   |     |                     |                |
| comment_count         | bigint(20)          | NO   |     | 0                   |                |
+-----------------------+---------------------+------+-----+---------------------+----------------+
23 rows in set (0.01 sec)

 文字列の検索置換を行うには、UPDATE構文でREPLACE関数を使うのがわかりやすい。この関数はマルチバイト文字列にも対応できている。

UPDATE テーブル SET カラム=REPLACE(カラム, 検索文字, 置換後文字);

たとえば、bootstrapのクラス「btn-success」の緑ボタンをやっぱり青い「btn-primary」に変更したい、しかも投稿全部にということがあったとする。そういう場合には、

mysql> UPDATE wp_posts SET post_content=REPLACE(post_content, 'class="btn btn-success"', 'class="btn btn-primary"');

のようなSQLを発行すればこれだけですべての記事の該当部分を置換できる。もちろん投稿すべて(wp_postsのpost_content)が置換されることになるので、置換すべきところを特定するには、検索文字で条件を絞るか、WHERE条件などを付けることに注意は必要である。

実際、上記のまま実行すると、置換対象のカラムとして自動保存された履歴や下書きも対象になり、実行後に表示される、

Query OK, 146 rows affected (0.03 sec)
Rows matched: 522 Changed: 146 Warnings: 0

matchedやChangedの数が想定よりかなり多くなってしまうだろう。とくに気にしないというのもありではあるが、最低限公開記事のみ(post_status='publish')などのWHEREは入れておくのが良い。

mysql> UPDATE wp_posts SET post_content=REPLACE(post_content, 'class="btn btn-success"', 'class="btn btn-primary"') where post_status='publish';