2011-11-25 16 views
5

Debido a errores de mis predecesores, una base de datos (MySQL) que quisiera utilizar contiene muchas entidades HTML (por ejemplo, € en lugar de ).Eliminar entidades html de una base de datos

Como la base de datos debe contener datos brutos (una base de datos no debería tener nada que ver con HTML) quiero eliminarlos del DB y almacenarlos en el UTF8 correcto, la ubicación ya es esa.

¿Cuál sería una buena manera de arreglar esto? Lo único que se me ocurre es escribir un script PHP que obtenga todos los datos, lo ejecute a través de html_entity_decode() y lo vuelva a escribir. Es factible ya que es una operación de una sola vez y la base de datos tiene solo unos 100 MB de tamaño, pero sigue siendo menos que óptima.

¿Alguna idea?

+0

Si se trata de sólo unos pocos caracteres diferentes, que probablemente podría hacer una consulta de actualización con una cuerda sencilla buscar/reemplazar Pero si es una gran variedad, entonces elija la opción de ida y vuelta de PHP. –

+0

Hay más de 50 entidades en uso solo en esta base de datos, y HTML permite que cada carácter se escriba como una entidad HTML utilizando la sintaxis &#xxx;, por lo que no es tan simple como buscar y reemplazar. – dtech

Respuesta

2

Dado que nadie podía proporcionar una solución satisfactoria solo de SQL, la resolví con un script similar a este. Tenga en cuenta que sólo funciona si todas las tablas que lo uso en tener una clave principal, pero esto suele ser el caso

<?php 
// Specify which columns need to be de-entitiezed 
$affected = array(
    'table1' => array('column1', 'column2'), 
    'table2' => array('column1', 'column2'), 
); 

// Make database connection 
$db = new PDO("mysql:dbname=yourdb;host=yourhost", "user", "pass"); 

foreach($affected as $table => $columns){ 
    // Start a transaction for each table 
    $db->beginTransaction(); 

    // Find the table primary key. PHP5.4 syntax! 
    $pk = $db->query("SHOW INDEX FROM " . $table . " WHERE Key_name = 'PRIMARY'")->fetch()[0]; 

    foreach($columns as $column){ 
     // Construct a prepared statement for this column 
     $ps = $db->prepare("UPDATE " . $table . " SET " . $column . " . = ? WHERE " . $pk . " = ?"); 

     // Go through all rows 
     foreach($db->query("SELECT " . $column . ", " . $pk . " FROM " . $table) as $row){ 
      $row[0] = html_entity_decode($row[0]); // Actual processing 
      $ps->execute($row); 
     } 
    } 

    // Everything went well for this table, commit 
    $db->commit(); 
} 
?> 
0

Dependiendo de la base de datos (Oracle, MySql, etc.) y si puede desconectarlo, puede exportar todos los DDL y datos como un script SQL grande (que contiene INSERT para todas las tablas). Posteriormente, se podría hacer una búsqueda estándar/reemplazar el uso de sed:

sed -i 's/&euro;/€/g' script.sql 

a continuación, colocar la base de datos o truncar las tablas y volver a crearla con el script.

0

En última instancia, creo que vas a tener que recurrir a PHP en algún momento, la conversión de muchas de estas características en SQL generará una gran cantidad de lógica de desición.

Sin embargo, un enfoque que puedo pensar si debe utilizar SQL, es crear una función definida por el usuario, que absoluto se refiere tiene una declaración de caso muy importante en (o un montón de si/entonces es):

http://dev.mysql.com/doc/refman/5.0/en/case-statement.html 

Entonces simplemente debería ser capaz de hacer algo como:

SELECT col1,col2,col3,mtuserdecodefunction(column-with-entities-in) FROM mytable 

Lo que en teoría debería devolverle una mesa limpia.

1

Creo que necesita crear un procedimiento mysql. (con SELECT loop y update replace)
REPLACE(TextString, '&apos;','"') ;

Cuestiones relacionadas