Как исправить двойное кодирование в PostgreSQL? - PullRequest
5 голосов
/ 18 ноября 2011

У меня есть таблица в PostgreSQL со словами, но некоторые слова имеют недопустимые символы UTF-8, такие как 0xe7e36f и 0xefbfbd.

Как я могу определить все символы внутри слов, которые являются недействительными, и заменить ихс таким символом, как ??

EDIT : Моя база данных находится в UTF-8, но я думаю, что есть двойное кодирование из различных других кодировок.Я думаю, что это потому, что когда я пытался преобразовать в один тип как LATIN1, я получаю сообщение об ошибке, в котором говорится, что в этой кодировке не существует какой-либо символ, при переходе на LATIN2 я получаю ту же ошибку, но с другим символом.

Итак, что можно сделать, чтобы решить эту проблему?

1 Ответ

0 голосов
/ 19 ноября 2011

Использование

Это решение для моего конкретного случая, но, возможно, с некоторыми изменениями может помочь другим людям.

Использование

SELECT fix_wrong_encoding('LATIN1');

Функция

-- Convert words with wrong encoding
CREATE OR REPLACE FUNCTION fix_wrong_encoding(encoding_name VARCHAR)
RETURNS VOID
AS $$
DECLARE     
    r RECORD;
    counter INTEGER;
    token_id INTEGER;
BEGIN
    counter = 0;
    FOR r IN SELECT t.id, t.text FROM token t
    LOOP
        BEGIN
            RAISE NOTICE 'Converting %', r.text;
            r.text := convert_from(convert_to(r.text,encoding_name),'UTF8');
            RAISE NOTICE 'Converted to %', r.text;
            RAISE NOTICE 'Checking existence.';
            SELECT id INTO token_id FROM token WHERE text = r.text;             
            IF (token_id IS NOT NULL) THEN
                BEGIN
                    RAISE NOTICE 'Token already exists. Updating ids in textblockhastoken';
                    IF(token_id = r.id) THEN
                        RAISE NOTICE 'Token is the same.';
                        CONTINUE;
                    END IF;
                    UPDATE textblockhastoken SET tokenid = token_id
                    WHERE tokenid = r.id;
                    RAISE NOTICE 'Removing current token.';
                    DELETE FROM token WHERE id = r.id;
                END;
            ELSE
                BEGIN
                    RAISE NOTICE 'Token don''t exists. Updating text in token';
                    UPDATE token SET text = r.text WHERE id = r.id;
                END;
            END IF;
            EXCEPTION WHEN untranslatable_character THEN
                --do nothing
            WHEN character_not_in_repertoire THEN
                --do nothing
            END;
            counter = counter + 1;
            RAISE NOTICE '% token converted', counter;
    END LOOP;
END
$$
LANGUAGE plpgsql;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...