Задолго до того, как я что-то знал – не то, что я знаю многое даже сейчас – я отложил веб-приложение в php, которое вставляло данные в мою базу данных mysql после запуска значений через htmlentities()
. Я в конце концов опомнился и снял этот шаг и застрял на выходе, а не на входе, и продолжил свой веселый путь.
Однако с тех пор мне пришлось пересмотреть некоторые из этих старых данных, и, к сожалению, у меня проблема, когда она отображается на экране, я получаю значения, которые эффективно отображаются дважды.
Итак, есть ли способ mysql или phpmyadmin изменить все старые, затронутые строки обратно на соответствующие символы или мне придется написать скрипт для чтения каждой строки, декодирования и обновления всех 17 миллионов строк в 12 таблицах?
РЕДАКТИРОВАТЬ:
Спасибо за помощь всем, я написал свой собственный ответ ниже с некоторым кодом, это не очень, но он работал над тестовыми данными ранее, поэтому запрет кому-то указывать на явную ошибку в моем коде, пока я нахожусь в постели. Я буду запускать его на резервной БД завтра, а затем на живом, если это работает нормально.
Я закончил тем, что использовал это, не очень, но я устал, это 2 часа ночи, и он сделал свою работу! (Изменить: по данным теста)
$tables = array('users', 'users_more', 'users_extra', 'forum_posts', 'posts_edits', 'forum_threads', 'orders', 'product_comments', 'products', 'favourites', 'blocked', 'notes'); foreach($tables as $table) { $sql = "SELECT * FROM {$table} WHERE data_date_ts < '{$encode_cutoff}'"; $rows = $database->query($sql); while($row = mysql_fetch_assoc($rows)) { $new = array(); foreach($row as $key => $data) { $new[$key] = $database->escape_value(html_entity_decode($data, ENT_QUOTES, 'UTF-8')); } array_shift($new); $new_string = ""; $i = 0; foreach($new as $new_key => $new_data) { if($i > 0) { $new_string.= ", "; } $new_string.= $new_key . "='" . $new_data . "'"; $i++; } $sql = "UPDATE {$table} SET " . $new_string . " WHERE id='" . $row['id'] . "'"; $database->query($sql); // plus some code to check that all out } }
Поскольку PHP был методом кодирования, вы хотите использовать его для декодирования. Вы можете использовать html_entity_decode, чтобы преобразовать их обратно в исходные символы. Gotta loop!
Просто будьте осторожны, чтобы не расшифровать строки, которые ему не нужны. Не знаете, как вы это определите.
Я думаю, что писать сценарий php хорошо в этой ситуации. Вы можете использовать, как сказал Дэйв, функцию html_entity_decode () для преобразования ваших текстов назад.
Сначала попробуйте свой скрипт на столе с несколькими записями. Это позволит вам сэкономить много времени на тестирование. Конечно, не забудьте сделать резервную копию своих таблиц перед запуском php-скрипта.
Боюсь, что нет более короткой возможности. Вычисление для миллионов строк остается довольно дорогостоящим, независимо от того, как вы конвертируете данные. Так что идите на php-скрипт … это самый простой способ
Это немного kludgy, но я думаю, что массовое обновление – единственный способ пойти …
$Query = "SELECT row_id, html_entitied_column FROM table"; $result = mysql_query($Query, $connection); while($row = mysql_fetch_array($result)){ $updatedValue = html_entity_decode($row['html_entitied_column']); $Query = "UPDATE table SET html_entitied_column = '" . $updatedValue . "' "; $Query .= "WHERE row_id = " . $row['row_id']; mysql_query($Query, $connection); }
Это упрощено, не обрабатывается ошибка и т. Д. Не уверен, что время обработки будет на миллионы строк, поэтому вам может понадобиться разбить его на куски, чтобы избежать тайм-аутов сценария.
У меня была точно такая же проблема. Поскольку у меня было несколько клиентов, работающих под управлением приложения, я хотел избежать использования PHP-скрипта для очистки базы данных для каждого из них.
Я придумал решение, которое далека от совершенства, но делает работу безболезненно.
Измените свой метод «отображения данных как HTML» на что-то вроде этого:
return html_entity_decode (htmlentities ($ chaine, ENT_NOQUOTES), ENT_NOQUOTES);
Процесс отмены-повтора выглядит смехотворным, но он выполняет эту работу. И ваша база данных будет медленно очищаться каждый раз, когда пользователи обновляют неверные данные.
Это моя пуленепробиваемая версия. Он выполняет итерацию по всем столбцам Tables и String в базе данных, определяет первичный ключ (ы) и выполняет обновления.
Он предназначен для запуска php-файла из командной строки для получения информации о ходе работы.
<?php $DBC = new mysqli("localhost", "user", "dbpass", "dbname"); $DBC->set_charset("utf8"); $tables = $DBC->query("SHOW FULL TABLES WHERE Table_type='BASE TABLE'"); while($table = $tables->fetch_array()) { $table = $table[0]; $columns = $DBC->query("DESCRIBE `{$table}`"); $textFields = array(); $primaryKeys = array(); while($column = $columns->fetch_assoc()) { // check for char, varchar, text, mediumtext and so on if ($column["Key"] == "PRI") { $primaryKeys[] = $column['Field']; } else if (strpos( $column["Type"], "char") !== false || strpos($column["Type"], "text") !== false ) { $textFields[] = $column['Field']; } } if (!count($primaryKeys)) { echo "Cannot convert table without primary key: '$table'\n"; continue; } foreach ($textFields as $textField) { $sql = "SELECT `".implode("`,`", $primaryKeys)."`,`$textField` from `$table` WHERE `$textField` like '%&%'"; $candidates = $DBC->query($sql); $tmp = $DBC->query("SELECT FOUND_ROWS()"); $rowCount = $tmp->fetch_array()[0]; $tmp->free(); echo "Updating $rowCount in $table.$textField\n"; $count=0; while($candidate = $candidates->fetch_assoc()) { $oldValue = $candidate[$textField]; $newValue = html_entity_decode($candidate[$textField], ENT_QUOTES | ENT_XML1, 'UTF-8'); if ($oldValue != $newValue) { $sql = "UPDATE `$table` SET `$textField` = '" . $DBC->real_escape_string($newValue) . "' WHERE "; foreach ($primaryKeys as $pk) { $sql .= "`$pk` = '" . $DBC->real_escape_string($candidate[$pk]) . "' AND "; } $sql .= "1"; $DBC->query($sql); } $count++; echo "$count / $rowCount\r"; } } } ?>
приветствует Роланда