Как вставить несколько записей и получить значение идентификатора?

Я вставляю несколько записей в таблицу A из другой таблицы B. Есть ли способ получить значение идентификатора таблицы A для записи и записи в таблице b без выполнения курсора?

Create Table A
(id int identity,
Fname nvarchar(50),
Lname nvarchar(50))

Create Table B
(Fname nvarchar(50),
Lname nvarchar(50),
NewId int)

Insert into A(fname, lname)
SELECT fname, lname
FROM B

Я использую MS SQL Server 2005.

0
добавлено отредактировано
Просмотры: 39
Ответ Энди Ирвинг - лучший. Триггеры неуклюжи и не работают хорошо для произвольных операций на вашей целевой таблице, особенно если ваша цель является временной или просто промежуточной. Ответ Даррена неверен, если вы вставляете набор строк, их порядок в целевой таблице не обязательно совпадает с порядком вашего набора. Путь Дмитрия плохой, потому что ему требуется цикл вокруг вставки одной строки за раз, что является медленной производительностью, всегда используйте наборы, когда сможете. Кори плохо, и он объяснил, почему, «пока они не конфликтуют». Это произойдет в субботу вечером c
добавлено автор clemahieu, источник
Я понимаю, что это старый вопрос, и он указывает SQL Server 2005, но поскольку это первый результат, чтобы показать заявление MERGE, доступное в 2008 году, и позже следует упомянуть тех, кто ищет решение. MERGE INTO TargetTable ИСПОЛЬЗОВАНИЕ (SELECT ....) AS Source ON 1 = 2 КОГДА НЕ СКАЗАНО ТОГДА ВСТАВИТЬ .... ВЫХОД вставлен.ID INTO TempTable (InsertedID)
добавлено автор oldegreyg, источник
Вам не нужно слияние для простой вставки. Слияние полезно для вставки/обновления, но избыток для простой вставки. Выходной ответ Энди помог мне и помог снять блокировку индекса.
добавлено автор CodeMonkeyForHire, источник

7 ответы

Вы можете получить, присоединившись к номер строки . Это возможно, потому что, поскольку это идентификатор, он будет просто увеличиваться по мере добавления элементов, которые будут в том порядке, в котором вы их выбираете.

0
добавлено
Неверно, записи не гарантируются для входа в базу данных в том порядке, в котором вы думаете, что они идут.
добавлено автор HLGEM, источник

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

Для этого вам просто нужно включить идентификационную вставку в таблице A. Это позволит вам определить ваш идентификатор вставить и до тех пор, пока они не конфликтуют, вы должны быть в порядке. Тогда вы можете просто сделать:

Insert into A(identity, fname, lname) SELECT newid, fname, lname FROM B

Не знаете, какую БД вы используете, но для сервера sql команда для включения вставки идентификатора:

set identity_insert A on
0
добавлено
Он не пытается обновить таблицу A, он пытается обновить таблицу B. В таблице B нет столбца идентификации.
добавлено автор njr101, источник

Внимательно прочитав ваш вопрос, вы просто хотите обновить таблицу B на основе новых значений идентичности в таблице A.

После того, как вставка закончена, просто запустите обновление ...

UPDATE B
SET NewID = A.ID
FROM B INNER JOIN A
     ON (B.FName = A.Fname AND B.LName = A.LName)

Это предполагает, что комбинация FName/LName может использоваться для сопоставления записей между таблицами. Если это не так, вам может потребоваться добавить дополнительные поля, чтобы гарантировать соответствие записей.

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

0
добавлено

МБелли прав на деньги. Но тогда триггер будет всегда пытаться обновлять таблицу B, даже если это не требуется (потому что вы также вставляете из таблицы C?).

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

Если бы это был я, и было не критично, я бы пошел с курсором.

0
добавлено

Если вы всегда этого хотите, вы можете установить триггер AFTER INSERT в TableA, который обновит таблицу B.

0
добавлено

Я предлагаю использовать тип uniqueidentifier вместо идентификатора. В этом случае вы можете генерировать идентификаторы перед вставкой:

update B set NewID = NEWID()

insert into A(fname,lname,id) select fname,lname,NewID from B
0
добавлено

Используйте предложение ouput с 2005 года:

DECLARE @output TABLE (id int)

Insert into A (fname, lname)
OUTPUT inserted.ID INTO @output
SELECT fname, lname FROM B

select * from @output

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

0
добавлено
@munissor, я знаю, что это старая нить, но посмотрите это простая статья по этому вопросу. Посмотрите раздел «Добавление предложения OUTPUT».
добавлено автор Mr Moose, источник
Обратите внимание, что это терпит неудачу, когда таблица A имеет триггер, потому что ошибка, которую Microsoft отказывается исправить. Другое обходное решение находится здесь: stackoverflow.com/q/13198476/2557263
добавлено автор Alejandro, источник
@munissor немного поздно, но вы можете сделать output insert.id, insert.whateverColumn в @output
добавлено автор Dennis Rongo, источник
Но тогда как вы обновляете таблицу B? Я имею в виду, как вы связываете каждую запись @output с записью в B? Если вы используете fname, lname в качестве ключа, то проще использовать решение njr.
добавлено автор munissor, источник
@DennisRongo только если вставлен. WhateverColumn - это еще один уникальный идентификатор ...
добавлено автор Mark, источник