Запрос захвата ORACLE, вызывающий переполнение таблицы

1

Я столкнулся с проблемой, когда процесс Java (который я не контролирую) вставляет строки в таблицу и вызывает переполнение. Я не могу перехватить запросы, и исключение, созданное ORACLE, не является информативным. Он упоминает только переполнение, но не тот столбец, в котором он происходит.

Я хотел бы знать, какой запрос вызывает это переполнение, а также значения, которые вставлены.

Я попытался создать триггер ПЕРЕД ВСТАВКОЙ в таблице, которая копирует строки в другую временную таблицу, которую я могу позже прочитать, однако похоже, что триггер не запускается, когда происходит переполнение.

Синтаксис триггера:

CREATE OR REPLACE TRIGGER OVERFLOW_TRIGGER
BEFORE INSERT
    ON VICTIM_TABLE
    FOR EACH ROW
BEGIN
    insert into QUERIES_DUMP values (
        :old.COL1, :old.COL2, :old.COL3, 
        :old.COL4, :old.COL5, :old.COL6, 
        :old.COL7, :old.COL8, :old.COL9, 
        :old.COL10, :old.COL11, :old.COL12
    );
END;
/

Таблица QUERIES_DUMP имеет одинаковую структуру таблицы сбоев, однако столбцы NUMBER и VARCHAR2 отбрасываются до максимальной емкости. Я надеюсь получить список запросов, а затем выяснить, какие из них нарушают правила.

Ожидается ли, что триггер не будет запущен в случае переполнения, даже если он установлен для запуска перед вставкой?

SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - Prod
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Solaris: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

EDIT1:

Возникающая ошибка:

Description: Error while query: INSERT INTO 
...
ORA-01438: value larger than specified precision allowed for this column

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

Я подумал о резервном копировании таблицы и создании новой жертвы с большими столбцами, но процесс фактически вставляется во множество других таблиц, а также в сложную datamodel, и БД имеет несколько конфиденциальную информацию, поэтому я не могу поставить под угрозу ее согласованность перемещая вещи вокруг.

Я попробовал триггер INSTEAD OF, но ORACLE, похоже, не принимает INSTEAD OF для вставок на таблицу.

Я добавил запись на уровне JDBC, но у моих запросов не было значений, только "?"

Description: Error while query: INSERT INTO VICTIM_TABLE ( . . . ) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
  • 0
    Вы должны сделать свою вставку в автономной транзакции . Это откатывается.
  • 1
    Включите трассировку, затем запустите TKPROF.
Теги:

1 ответ

1
Лучший ответ

Это зависит от конкретной ошибки (включая номер ошибки ORA-xxxxx, которая всегда ценится).

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

Представьте, что произойдет, если проверки типов данных произойдут после запуска триггера. Если приложение Java передало недопустимое значение, скажем, col1, то внутри триггера :new.col1 будет иметь тип данных любого col1 в базовой таблице, но будет иметь недопустимое значение. Поэтому любая ссылка на это поле должна приводить к ошибке raised--, что вы не могли бы достоверно зарегистрировать недопустимое значение в своей таблице.

Вы уверены, что не можете как-то перехватить запросы? Например, если вы переименовали victim_table в victim_table_base, создали представление с именем victim_table с более крупными типами данных, а затем определили instead of триггера представление, которое проверило данные и вставило их в таблицу, вы могли бы определить, какие значения были недопустимыми. В качестве альтернативы, поскольку ваше приложение Java использует JDBC (предположительно) для взаимодействия с базой данных, вы должны иметь возможность включить ведение журнала на уровне JDBC, чтобы увидеть передаваемые значения параметров.

  • 0
    Большое спасибо за подробный ответ. Можете ли вы повторить мой вопрос снова? Я обновил его с предложениями, которые вы дали.
  • 1
    @OdayMansour - если вы хотите использовать подход instead of триггера, вам нужно переименовать таблицу, создать представление и определить триггер в представлении. Вы не можете определить триггер instead of таблицы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню