Есть набор записей (0, 1, 2, 3, 4, 5) с некоторым количеством полей.
Есть primary key в таблице.
Есть insert into... sql statement.
Ситуация 1.
Пусть запись 2 со значением поля, соответствующему PK, значение, которое уже есть в базе, в остальных - отличается.
Если прибиндить весь массив и попытаться сделать OCIStmtExecute , то вставятся записи 0 и 1.
Всё отлично. Так и должно быть - после commit записи видны в других сессиях.
Ситуация 2.
Пусть в записях 1 и 2 значения полей, соответствующиз PK совпадают между собой, но отсутствуют в базе. Остальные - тоже отсутствуют.
Делается такой же OCIStmtExecute. В ответ я ожидаю, что по крайней мере запись 0 добавится в базу. Но этого не происходит.
(nb: во втором случае, естесственно также делается commit)
Вопрос - куда копать. Вдруг кто знает.
"папа, а ты сейчас с кем разговаривал?"
ReplyDeleteПохоже, что изменения фиксируются только тогда, когда не нарушается целостность импортируемых данных.
ReplyDeleteВ первом случае сами 6 записей целостны, дублирования ключа нет. В этом случае вставка идет до нарушения целостности в самой базе данных, все удачные вставки фиксируются.
Во втором случае нарушена целостность в самих 6 записях. Видимо, OCIStmtExecute сначала проверяет целостность импортируемых данных. Если она нарушена, то импорт не происходит вообще, поэтому commit и не фиксирует вставку записи с номером 0 (в указанном выше примере).
Механизм работы OCIStmtExecute мне неизвестен, но можно предположить, что существуют ошибки после которых работа OCIStmtExecute аварийно завершается. Судя по всему, нарушения целостности внутри самих импортируемых данных входят в этот список.
P.S. Кстати, я в зимнюю сессию вам экзамен по винде сдавал. Мир тесен ;)
что либо целостность проверяется иначе, либо есть какая-то "внутренняя" транзакция, в которой говорится rollback в случае определённого противоречия.
ReplyDeleteТут собственно иных вариантов-то нет, осталось найти доку, в которой это постулируется, первоисточник так сказать. Вопрос в том, почему такое разительное отличие в механзме проверки!
Насчет первоисточника ничем помочь не могу...
ReplyDeleteА почему различие? В обоих случаях проверка идет по одному алгоритму: 1) проверяется целостность вставляемых данных (между собой, если так можно выразиться), а потом 2) если сами вставляемые данные корректны, то производиться последовательная вставка в таблицу до первого нарушения целостности.
В рассмотренном выше примере в Случае 1 мы доходим до шага 2), т.е. вставка происходит до 1-й ошибки ;в Случае 2 останавливаемся на шаге 1), т.е. вставка в таблицу не происходит вообще из-за того, что функция посчитала импортируемые данные некорректными
Все это ИМХО, основанное на приведенном примере. Точно утверждать не могу
На самом деле это легко проверить, BTW. Надо попробовать на каком-нибудь другом языке ( не с++ ) попробовать сделать batch insert. Всего делов-то!
ReplyDeleteМда, я, кажется, не помогу.
ReplyDeleteСлова все знакомые :) Но смысл ускользает.
Ой, прочитала дискуссию:))) Оказывается, что PK - это праймэри кэй я не доперла :)
ReplyDelete...копать в сторону OCI_BATCH_ERRORS
ReplyDeleteи т.д. ...
Видимо всё же то, что Oracle добавляет записи в первом случае последовательно - некая случайность (хотя с другой стороны, именно в случае batch insert можно было бы ожидать и то, что такое поведение нормально). А вот во втором случае уже всё не так хорошо, а OCI_BATCH_ERRORS позволяет получить коллекцию(?) ошибок, с помощью которых (которой) уже можно отследить сбойную (сбойные) записи, что есть good.