| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > MS SQL Server > Получение identity в batch insert-е |
| Автор: Любитель 18.9.2009, 22:07 | ||
| Думаю, что понятней будет изложить проблему целиком (ну.. конечно, в максимально упрощённом виде). Итак, есть: 1. Таблица иерарических данных с полями ID, ParentID и Name. Назовём её Options. 2. XML с иерархическими данными, скажем с тегами Item и именем в аттрибуте Name. 3. Надо данные из XML-а вставить в базу как можно эффективнее. Был рассмотрен такой вариант (надеюсь не ошибся, ибо пишу из дома, по памяти), он работает, но ориентирован на GUID-овые айдишники:
Вопрос - можно ли как-то заставить работать такой же запрос, но при использование identity-айдишников? В идеале нужна функция, которая позволяла бы получить следующее значение для внутреннего значения identity таблицы и меняла это значение. Разрешить явную вставку значения айдишника - уже не проблема, конечно. Замечу, что просто базироваться на значении identity до вставок нельзя (и прибавлять к нему, условно говоря, номер элемента) - так как это нарушить возможность многопользовательской вставки. Что посоветуете? |
| Автор: Akina 18.9.2009, 22:25 |
| ммм... IDENT_CURRENT? Как я понимаю, тебе что новый identity, что последний+seed - пофиг, сложить-то сумеешь, а шаг получить несложно. Добавлено через 4 минуты и 20 секунд Правда, ориентироваться на вычисленное таким образом значение можно только если эта транзакция блокирует вставку в таблицу... |
| Автор: Zioma 18.9.2009, 23:10 | ||
Вы имеете ввиду Оракл? |
| Автор: Любитель 18.9.2009, 23:16 |
| Ну.. из того, с чем работал - оракл, постгри. Вообще - я про концепцию (генерация уникальных значений инкриментом), а не конкретную реализацию. identity в MS SQL реализует эту концепцию, но.. либо неполно (с точки зрения "ручной" работы), либо я что-то не понимаю. |
| Автор: kobra 19.9.2009, 15:57 |
| если я правилно понял задачу, тооптималнее будет вставить липовую запис, получить идентификатор, а потом модифицировать на нужный. конечно можно разрешить вставку в поле идентити своего значения, но при многоползователском доступе, опасно |
| Автор: Любитель 19.9.2009, 16:08 |
| Да, вообщем-то примерно так я вначале и сделал. Для конечного восстановления парент-айдишника были добавлены две колонки: номер и парент-номер в пределах одной кампании (одного XML-файла). А затем апдейтил ParentID по ним. Но, как оказалось, для больших XML-ей (дело даже не в размере - порядка нескольких мегабайт, а во вложенности) производительность оставляла желать лучшего. Причём дело не в апдейте (там были созданы соответствующие индексы), основные затраты были на прасинг XML всё-таки. Поэтому всё-таки, поменяли формат файла (к счастью, оказывается никого он не волновал), на линейный XML, в которым прописывались номера (подряд) и номера парентов при его экспорте в клиентском приложении. Сейчас в хранимку грузится линейный XML (с прописанной иерархией в виде отношений), затем апдейтятся реальные ParentID. Всё работает быстро, все довольны |
| Автор: Akina 19.9.2009, 16:17 | ||
Не-а. Очередное значение генерится один раз, и непременно последовательное. Попробуй: Открой транзакцию А, затем транзакцию Б, в Б сгенери identity, затем сделай её откат, затем сгенери identity в транзакции А. Как полагаешь, что получится в транзакции А? |
| Автор: Любитель 19.9.2009, 16:46 |
| Мм.. Предполагаю, что на 2 больше, чем вначале. Сейчас проверю |
| Автор: Любитель 19.9.2009, 17:04 |
| Ну.. Так и есть. Или я что-то не так понял? |
| Автор: Akina 19.9.2009, 18:30 |
| Ну... и о каких там "учётах возможностей" может идти речь? Очередной identiny или был сгенерён, или нет. Третьего не дано. Если мы получили очередное значение у СУБД - неважно, для использования или "на посмотреть" - всё, оно сгенерено, занято, больше не сгенерится. А учитываться ничего не будет, оно никому не надо. Кто попросит, тот получит. А использовать или нет - это его дело. |
| Автор: Любитель 20.9.2009, 18:22 |
| Да не - я не то имел ввиду. Я имел ввиду, что если взять текущее значение (IDENT_CURRENT) перед вставкой, а остальные рассчитать подряд - получится ерунда. А вот если бы была функция, которая инкрементила идентити и возвращала новое значение - то можно было бы решить начальную задачу (с включенным для нашей таблицы IDENTITY_INSERT). |