Mysql
 sql >> база данни >  >> RDS >> Mysql

mysql замества специалните html знаци с UTF еквиваленти

Както е посочено в моят коментар по-горе /a> , ужасно неясно е какво се опитвате да направите в собствения си случай.

Е да. Можете да замените символни кодови обекти (напр. { и ƫ ) с техните заместващи знаци, без да се налага да търсите кода на знака в „картографиране“. Но наименувани обекти (напр. " ) винаги ще трябва да се търси.

Ето моя опит да разреша общия случай:

  1. Създайте таблица за съхраняване на наименувани знаци, дефинирани в HTML:

    CREATE TABLE ents (
      ref VARCHAR(8) NOT NULL COLLATE utf8_bin,
      rep CHAR(1)    NOT NULL,
      PRIMARY KEY (ref)
    );
    
  2. Попълнете тази таблица - предлагам да използвате скрипт, например от PHP:

    $dbh = new PDO("mysql:dbname=$dbname", $username, $password);
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE);
    $ins = $dbh->prepare('INSERT INTO ents (ref, rep) VALUES (?, ?)');
    $t = get_html_translation_table(HTML_ENTITIES);
    foreach ($t as $k => $v) $ins->execute([substr($v, 1, -1), $k]);
    
  3. Дефинирайте SQL функция за извършване на замествания на обекти (използвайки тази таблица, където е приложимо, или чрез код на символа):

    DELIMITER ;;
    
    CREATE FUNCTION dhe(s TEXT) RETURNS TEXT
    BEGIN
      DECLARE n, p, i, t INT DEFAULT 0;
      DECLARE r VARCHAR(12);
      entity_search: LOOP
        SET n := LOCATE('&', s, n+1);
        IF (!n) THEN
          LEAVE entity_search;
        END IF;
    
        IF (SUBSTRING(s, n+1, 1) = '#') THEN
          CASE
            WHEN SUBSTRING(s, n+2, 1) RLIKE '[[:digit:]]' THEN
              SET t := 2, p := n+2, r := '[[:digit:]]';
            WHEN SUBSTRING(s, n+2, 1) = 'x' THEN
              SET t := 3, p := n+3, r := '[[:xdigit:]]';
            ELSE ITERATE entity_search;
          END CASE;
        ELSE
          SET t := 1, p := n+1, r := '[[:alnum:]_]';
        END IF;
    
        SET i := 0;
        reference: LOOP
          IF SUBSTRING(s, p+i, 1) NOT RLIKE r THEN
            IF SUBSTRING(s, p+i, 1) RLIKE '[[:alnum:]_]' THEN
              ITERATE entity_search;
            END IF;
            LEAVE reference;
          END IF;
          IF i = 8 THEN ITERATE entity_search; END IF;
          SET i := i + 1;
        END LOOP reference;
    
        SET s := CONCAT(
          LEFT(s, n-1),
          CASE t
            WHEN 1 THEN COALESCE(
              (SELECT rep FROM ents WHERE ref = SUBSTRING(s, p, i))
            , SUBSTRING(s, n, i + IF(SUBSTRING(s, p+i, 1)=';',1,0))
            )
            WHEN 2 THEN CHAR(SUBSTRING(s, p, i))
            WHEN 3 THEN CHAR(CONV(SUBSTRING(s, p, i), 16, 10))
          END,
          SUBSTRING(s, p + i + IF(SUBSTRING(s, p+i, 1)=';',1,0))
        );
      END LOOP entity_search;
      RETURN s;
    END;;
    
    DELIMITER ;
    
  4. Приложете тази функция два пъти за да декодирате вашата (очевидно) двойно кодирана таблица:

    UPDATE my_table SET my_column = dhe(dhe(my_column));
    


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Преобразуване на MyISAM в InnoDB. Благоприятно? Последствия?

  2. Разлика в датата в MySQL за изчисляване на възрастта

  3. Експортирайте MySQL база данни с PHP

  4. Изисква се пролетно зареждане CLIENT_PLUGIN_AUTH

  5. кешът на заявките не работи