OracleBulkCopy не поддерживает триггеры

Моему программному обеспечению необходимо вставить около 5000 записей в базу данных Oracle одновременно, поэтому я использовал OracleBulkCopyдля этого. Моя таблица использует триггер для автоматического увеличения первичного ключа. Но исключение OracleBulkCopythrow «ORA-26086: прямой путь не поддерживает триггеры».

Итак, как я могу использовать первичный ключ OracleBulkCopy и автоинкремент?


person hieund    schedule 14.06.2013    source источник


Ответы (3)


Распространенным решением для такого типа сценариев является выполнение массовой загрузки в промежуточную таблицу; отдельная таблица без триггеров и т. д., в которую можно быстро добавить данные. Это означает, что вы получаете преимущество массовой загрузки с точки зрения пропускной способности и производительности в оба конца. Потом; когда и только когда данные находятся в промежуточной таблице, используйте обычный SQL (предположительно insert) для перемещения данных из промежуточной таблицы в фактическую транзакционную таблицу. Тогда это полностью локальный сервер базы данных, поэтому он очень быстрый.

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

person Marc Gravell    schedule 14.06.2013
comment
@hieund какой бит был неясен ...? 2 таблицы, ваша существующая обычная таблица с триггерами и т. д., и вторая таблица, которая не работает; массовая вставка во вторую таблицу, затем переместите данные с помощью insert... - person Marc Gravell; 26.06.2013
comment
Да, моя проблема в том, что если у меня есть 100 таблиц, я должен создать еще 100 таблиц с той же структурой, чтобы использовать массовую вставку для каждой таблицы. Так что моя база данных имеет 200 таблиц, это слишком много и сложно поддерживать. Очень полезно, если есть таблица, которая может представлять для этих других 100 таблиц. - person hieund; 27.06.2013

Из Руководства разработчика ODP.Net следует, что класс OracleBulkCopy загрузка прямого пути. Как указывает ошибка, вы не можете выполнить прямую загрузку в таблицу с включенными триггерами.

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

person Justin Cave    schedule 14.06.2013

Решение Джастина Кейва легко реализовать, но есть одна проблема. Это мои шаги должны быть:

  1. Отключить триггер
  2. Получить 5000 идентификаторов из последовательностей
  3. Присвоить идентификаторы записям
  4. Выполнить массовую вставку в базу данных
  5. Включить триггер

Если пользователь находится на шаге 2 (или 3, 4) - он отключил триггер. И другой пользователь в другом контексте также вставляет запись в мою таблицу в это время, так что он не может получить увеличенный идентификатор;

Решение Марка Гравелла кажется очень хорошим. Но мне трудно добиться. Мой проект использует Entity Framework. Вы имеете в виду, что: с каждой таблицей в базе данных я должен создать другую таблицу с той же структурой?

person hieund    schedule 17.06.2013
comment
Это было давно. Но я думаю, что мы не должны отключать триггер. Просто проверьте, является ли входной идентификатор триггера нулевым или нулевым (0), а затем используйте последовательность. В противном случае просто используйте входной идентификатор. - person hieund; 23.01.2018