Здравствуйте, mangaman, Вы писали:
M>Или подскажите, можно ли сделать INSERT с получением созданного primary key не построчно, а как-то быстрее, блоками?
Можно получить все сгенерированные identity значения через OUTPUT секцию:
insert table1 (data1)
output inserted.id
values('a'), ('b'), ('c')
M>Подскажите какой-то более оптимальный способ заполнения связанных таблиц.
Сходу вижу два способа.
Первый. На время загрузки отключить генерацию identity для этих таблиц и проверку внешних ключей. Заполнить id поля в обоих наборах данных на стороне клиента и залить в каждую таблицу bulk insert. Потом включить identity / foreign keys обратно. Не очень красиво с т.з. СУБД, но при монопольном доступе к БД (или по крайне мере к этим таблицам) — должно работать ок.
Второй. Создать специальные staging таблицы в БД, которые по структуре будут как основные, но без identity полей. Залить туда данные bulk insert с клиента. После чего запустить SQL запрос, который в одной транзакции перельет данные из staging таблиц в основные и правильно заполнить id поля. Сгенерированные identity значения опять таки можно получить через OUTPUT, но не передавать на клиент, а сохранить во временную таблицу и сджоинить их сразу с данныим из staging таблиц. Потом staging таблицы можно почистить с помощью TRUNCATE.
Еще экзотические варианты:
* Сделать хранимую процедуру, которая будет принимать два табличных параметра (table valued parameters). Соответственно реализовать логику вставки как в предыдущем случае, но внутри ХП. Не использовал такое на практике, поэтому не скажу насколько быстро будет работать и легко ли реализовать.
* Подумать о передаче связанных данных на сторону БД через XML, а там уже парсить (есть встроенная поддержка) и вставлять.