Как исправить эту проблему с хранимой процедурой

sql sqlbulkcopy sql-server

Вопрос

У меня 2 таблицы. Ниже приведены только обезжиренные версии этих таблиц.

TableA
Id <pk> incrementing
Name varchar(50)

TableB
TableAId <pk> non incrementing
Name varchar(50)

Теперь эти таблицы имеют отношение друг к другу.

сценарий

Пользователь 1 приходит на мой сайт и выполняет некоторые действия (в этом случае добавляет строки в таблицу A). Поэтому я использую SqlBulkCopy для всех этих данных в таблице A.

Однако мне нужно добавить данные также в таблицу B, но я не знаю вновь созданного идентификатора из таблицы A, поскольку SQLBulkCopy не вернет их.

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

INSERT INTO TableB (TableAId , Name)
SELECT Id,Name FROM TableA as tableA
WHERE not exists( ...)

Однако это связано с проблемой. Пользователь в любое время может удалить что-то из TableB, поэтому, если пользователь удаляет строку, а затем появляется другой пользователь, или даже тот же пользователь приходит и делает что-то в таблице. Моя хранимая процедура вернет эту удаленную строку в таблицу B. Поскольку он все еще будет существовать в таблице A, но не в таблице B и, таким образом, будет удовлетворять условию хранимой процедуры.

Итак, есть ли лучший способ справиться с двумя таблицами, которые необходимо обновлять при использовании массовой вставки?

Принятый ответ

SQLBulkCopy усложняет это, поэтому я бы рассмотрел использование промежуточной таблицы и предложение OUTPUT

Например, в смеси псевдокода клиента и SQL

create SQLConnection

Create #temptable
Bulkcopy to #temptable

Call proc on same SQLConnection

proc:
   INSERT tableA (..)
   OUTPUT INSERTED.key, .. INTO TableB
   SELECT .. FROM #temptable

close connection

Заметки:

  • соблазнительный будет локальным для соединения и изолирован

  • записи в А и В будут атомарными
  • накладывающиеся или более поздние записи, не заботятся о том, что происходит позже с A и B
  • подчеркивая последнюю точку, А и В будут только когда-либо заполняться из набора строк в #temptable

Альтернатива:

Добавьте еще один столбец в A и B, называемый sessionid, и используйте его для идентификации партий строк.


Популярные ответы

Как альтернативное решение, вы можете использовать триггеры базы данных для обновления второй таблицы.



Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Является ли этот КБ законным? Да, узнайте, почему