Поиск искаженного символа ` ` во всей базе данных - Oracle - PullRequest
2 голосов
/ 21 февраля 2012

Недавно мы исправили проблему с некорректным считыванием кодировки символов в нашу систему из текстовых файлов, убедившись, что это файл UTF-8 и код Java открывает эти файлы в кодировке UTF-8.

Однако мы закончили тем, что добавили много записей по всей таблице базы данных с вставленными неверными символами, т.е. °F читалось как �F.Поэтому, хотя мы исправили это сейчас, нам нужно очистить таблицы базы данных, чтобы исправить эту аномалию.

Может кто-нибудь предложить мне, как этого добиться?

1 Ответ

1 голос
/ 21 февраля 2012

У меня была похожая проблема некоторое время назад. К счастью, количество столбцов, на которые оно воздействовало, было ограничено небольшим числом, и эти столбцы имели одинаковое имя во всей базе данных.

Я решил это, написав скрипт, который выполняет следующее:

  1. отключить ограничения внешнего ключа
  2. составить список таблиц, которые содержат целевые столбцы
  3. обновить все таблицы в вашем списке, используя REGEXP_REPLACE
  4. фиксация данных, повторное включение ограничений

При этом использовалась здоровая доза динамического SQL, извлекающая данные из user_constraints и user_tab_columns, фильтрующая по именам конкретных столбцов, на которые я нацеливался.

Вот грубый скелет, с которого можно начать, я просто быстро его сложил, поэтому он не проверен. Кроме того, если у вас есть проблемы с триггерами, их тоже нужно отключить:

-- disable constraints
BEGIN
    FOR c IN (
        SELECT c.owner, c.table_name, c.constraint_name, c.constraint_type
        FROM user_constraints c
        INNER JOIN user_tables t ON (t.table_name = c.table_name)
        AND c.status = 'ENABLED'
        AND c.constraint_type NOT IN ('C', 'P')
        ORDER BY c.constraint_type DESC
    )
    LOOP
        dbms_utility.exec_ddl_statement('alter table '||c.table_name||' disable constraint ' || c.constraint_name);
    END LOOP;
END;

-- do the updates
BEGIN
    FOR t IN (
        SELECT table_name, column_name
        FROM user_tab_columns
        WHERE column_name = 'TEMPERATURE'
        AND data_type = 'VARCHAR2';
    )
    LOOP
        dbms_utility.exec_ddl_statement('UPDATE '||t.table_name||' SET ' ||t.column_name||' = '||''GOOD VALUE''||' WHERE '||t.column_name||' = '||''BAD VALUE'');
    END LOOP;
END;

-- re-enable constraints
BEGIN
    FOR c IN (
        SELECT c.owner, c.table_name, c.constraint_name, c.constraint_type
        FROM user_constraints c
        INNER JOIN user_tables t ON (t.table_name = c.table_name)
        AND c.status = 'DISABLED'
        AND c.constraint_type NOT IN ('C', 'P')
        ORDER BY c.constraint_type ASC
    )
    LOOP
        dbms_utility.exec_ddl_statement('alter table '||c.table_name||' enable constraint ' || c.constraint_name);
    END LOOP;
END;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...