2011-11-25 32 views
5

Do lỗi của người tiền nhiệm của tôi, cơ sở dữ liệu (MySQL) tôi muốn sử dụng chứa nhiều thực thể HTML (ví dụ: € thay vì ).Xóa thực thể html khỏi cơ sở dữ liệu

Vì cơ sở dữ liệu phải chứa dữ liệu thô (cơ sở dữ liệu không có gì để làm với HTML) Tôi muốn xóa chúng khỏi DB và lưu trữ nó theo đúng UTF8, sắp xếp thứ tự đã là vậy.

Điều gì sẽ là cách hay để khắc phục sự cố này? Điều duy nhất tôi có thể nghĩ đến là viết một kịch bản PHP nhận tất cả dữ liệu, chạy nó thông qua html_entity_decode() và viết nó trở lại. Đó là doable vì nó là một hoạt động một lần và DB chỉ khoảng 100MB lớn, nhưng nó vẫn còn ít hơn tối ưu.

Bất kỳ ý tưởng nào?

+0

Nếu nó chỉ là một vài nhân vật khác nhau, bạn có thể có thể làm một truy vấn cập nhật với chuỗi đơn giản tìm kiếm/thay thế. Nhưng nếu đó là một loạt, sau đó đi với tùy chọn khứ hồi PHP. –

+0

Có hơn 50 thực thể chỉ sử dụng trong cơ sở dữ liệu này và HTML cho phép mọi ký tự được viết dưới dạng thực thể HTML sử dụng cú pháp &#xxx;, vì vậy nó không đơn giản như tìm kiếm và thay thế. – dtech

Trả lời

2

Vì không ai có thể cung cấp giải pháp chỉ đáp ứng SQL, tôi đã giải quyết nó bằng tập lệnh tương tự như tập lệnh này. Lưu ý rằng nó chỉ có tác dụng nếu tất cả các bảng bạn sử dụng nó trên có một khóa chính, nhưng điều này thường sẽ là trường hợp

<?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

Tùy thuộc vào cơ sở dữ liệu (Oracle, MySql, v.v ...) và bạn có thể xuất tất cả DDL và dữ liệu dưới dạng tập lệnh SQL lớn (có chứa INSERT cho tất cả các bảng) hay không. Sau đó, bạn có thể thực hiện tìm kiếm tiêu chuẩn/thay thế bằng sed:

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

sau đó thả các cơ sở dữ liệu hoặc cắt xén các bảng và tạo lại nó bằng cách sử dụng kịch bản.

0

Cuối cùng tôi nghĩ bạn sẽ phải sử dụng PHP ở một giai đoạn nào đó, việc chuyển đổi rất nhiều trong số các entite này trong SQL sẽ làm mất đi một lượng lớn logic logic.

Tuy nhiên, Một cách tiếp cận tôi có thể nghĩ nếu bạn phải sử dụng SQL, là để tạo một người dùng được xác định chức năng, mà esentially có một tuyên bố trường hợp rất lớn trong (Hoặc nhiều nếu/sau đó là):

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

Sau đó, bạn chỉ đơn giản là có thể làm một cái gì đó như:

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

Nên trong lý thuyết trả lại cho bạn một bàn làm sạch.

1

Tôi cần phải tạo một thủ tục mysql. (với vòng lặp SELECT và cập nhật thay thế)
REPLACE(TextString, '&apos;','"') ;

Các vấn đề liên quan