Обновление вместо вставки.
В моей модели суррогатные ПК используются, но речь о не них сейчас не идет. Говорю о УНИКАЛЬНОМ СОСТАВНОМ КЛЮЧЕ/ПОЛЕ (Он же альтернативный ключ , АК, уникальный, УК, UK. Состоящий из нескольких полей одной таблицы, в которую добавляем данные). Дублировать ничего не надо. Просто, если новая запись будет не уникальной (по этому уникальному ключу), то надо провесли некоторые действия с имеющейся записью.
Это можно сделать простым SELECT (найти запись, повторив условия отбора). Но нужно, по возможности (для увеличения скорости ввода), убрать все лишние SELECT. При попытке вставить неуникальную запись, произойдет исключение, а это может выясниться только при создании уникального индекса новой записи (когда и выяснится, что она не уникальна). В общем, как получить rdb$db_key (именно той записи, на которой произошел сбой) на этом (после него СРАЗУ) этапе в этой процедуре?
Это можно сделать простым SELECT (найти запись, повторив условия отбора). Но нужно, по возможности (для увеличения скорости ввода), убрать все лишние SELECT. При попытке вставить неуникальную запись, произойдет исключение, а это может выясниться только при создании уникального индекса новой записи (когда и выяснится, что она не уникальна). В общем, как получить rdb$db_key (именно той записи, на которой произошел сбой) на этом (после него СРАЗУ) этапе в этой процедуре?
еще раз:
www.ibase.ru/devinfo/testiu.htm
вариант 3, с обработкой ошибок, БЕЗ селекта - САМЫЙ МЕДЛЕННЫЙ!
я вообще фигею - ссылку на статью дали, нет, человек про "скорость ввода" начинает, и про "без селекта"...
1. прочитанная запись
2. вставляемая/обновляемая запись
и делай с этим чего хочешь.
www.ibase.ru/devinfo/testiu.htm
вариант 3, с обработкой ошибок, БЕЗ селекта - САМЫЙ МЕДЛЕННЫЙ!
я вообще фигею - ссылку на статью дали, нет, человек про "скорость ввода" начинает, и про "без селекта"...
и как ты это собираешься сделать, не читая запись и не зная остальных столбцов записи? Тебе же надо чего-то там сделать, или сравнить. А с чтением у тебя естьто надо провесли некоторые действия с имеющейся записью.
1. прочитанная запись
2. вставляемая/обновляемая запись
и делай с этим чего хочешь.
никак. rdb$db_key это физический номер записи. узнать его можно только посредством select.КАК УЗНАТЬ RDB$DB_KEY ИМЕЮЩЕЙСЯ ЗАПИСИ В МОМЕНТ, КОГДА БЫЛА ПРЕДПРИНЯТА ПОПЫТКА ВСТАВКИ ЗАПИСИ С ТАКИМ ЖЕ ЗНАЧЕНИЕМ УНИКАЛЬНОГО КЛЮЧА, И ПОЛУЧЕН ОТКАЗ."
Также см. ответ Merlin-а.
p.s. мне интересно, сколько можно упираться против совершенно очевидных вещей?
p.p.s. допек ты меня. Объясняю. insert/update/delete могут обломиться по разным причинам. блокировка версии, constraint и т.п. При этом сервер только сообщает об ошибке, больше ничего. Никакие столбцы "ошибочной" записи, которая уже есть на диске, он не сообщает, никогда.
Даже если ты выполнил ПРЕДВАРИТЕЛЬНО select, и такой записи на диске НЕ ОКАЗАЛОСЬ, а потом ты делаешь insert, и получаешь key violation, то это может означать:
1. кто-то вставил запись но не сделал commit
2. твоя транзакия snapshot не может видеть даже committed изменения
3. для транзакции read_committed это означает, что в промежутке между select и insert кто-то успел вставить такую же запись.
А что Вы посоветуете, если вставка каждой записи делается в рамках одной (отдельной) распределенной транзакции (между несколькими БД) и процент совпадений еще ниже (оцениваю его максимум в 10%). Число записей на порядок выше.
Какой механизм эффективнее применять?
Большое Спасибо за ответы.
Значит обходного пути нет.
P.S.
to Merlin: RDB$DB_KEY (кстати, там написано, КОГО) мне нужен для следующего. НЕ ХОЧУ (не хотел, а приходится) делать SELECT по значению уникального ключа. Искал способ как этого не делать, а сразу получать его после сбоя.
to kdv: Вы в p.p.s забыли сказать, что сервер не просто сообщает, еще пытается обработать ошибку, если есть обработчик.
Какой механизм эффективнее применять?
Большое Спасибо за ответы.
Значит обходного пути нет.
P.S.
to Merlin: RDB$DB_KEY (кстати, там написано, КОГО) мне нужен для следующего. НЕ ХОЧУ (не хотел, а приходится) делать SELECT по значению уникального ключа. Искал способ как этого не делать, а сразу получать его после сбоя.
to kdv: Вы в p.p.s забыли сказать, что сервер не просто сообщает, еще пытается обработать ошибку, если есть обработчик.
Странный ты.pum писал(а):НЕ ХОЧУ (не хотел, а приходится) делать SELECT по значению уникального ключа.
Обычно стараются всё сделать в рамках PK, не трогая системные вещи, и залазя туда только в случае крайне жёстких требований к оптимизации.
Если каждая запись будет работать в рамках отдельной транзакции, и это жёсткое твоё условие, то тебе вообще пофиг, как делать. Потому как накладные расходы на старт/коммит транзакции перекроют любые твои выкрутасы.
По поводу вставки уже всё сказано. PK ничем не хуже чем RDB$DBKEY, и даже лучше во многих ситуациях.
По поводу транзакций - что-то не верится, что одна запись является в твоей задаче единичным логическим блоком, чтобы так работать. Транзакция переводит базу из одного логически целостного состояния в другое. У тебя это так?
По поводу транзакций - что-то не верится, что одна запись является в твоей задаче единичным логическим блоком, чтобы так работать. Транзакция переводит базу из одного логически целостного состояния в другое. У тебя это так?