Jak wstawić wiele rekordów i uzyskać wartość tożsamości?

Wstawiam wiele rekordów do tabeli A z innej tabeli B. Czy istnieje sposób, aby uzyskać wartość tożsamości rekordu tabeli a i zaktualizować rekord tabeli b bez wykonywania kursora?

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

Używam MS SQL Server 2005.

Author: Michał Powaga, 2008-09-18

7 answers

MBelly ma rację na pieniądze - ale wtedy WYZWALACZ zawsze będzie próbował zaktualizować tabelę B, nawet jeśli nie jest to wymagane (bo wstawiasz również z tabeli C?).

Darren również ma rację, nie można uzyskać wielu tożsamości z powrotem w wyniku zestawu. Twoje opcje to użycie kursora i wzięcie tożsamości dla każdego wiersza, który wstawisz, lub użycie podejścia Darrena do przechowywania tożsamości przed i po. Tak długo, jak wiesz, przyrost tożsamości to powinno działać, tak długo, jak ty upewnij się, że stół jest zablokowany dla wszystkich trzech zdarzeń.

Gdybym to ja, a nie czas krytyczny, wybrałbym kursor.

 -6
Author: Meff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 19:52:48

Użyj klauzuli ouput z 2005 roku:

DECLARE @output TABLE (id int)

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

select * from @output

Teraz twoja zmienna table ma wartości tożsamości wszystkich wstawianych wierszy.

 132
Author: Andy Irving,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-19 09:14:42

Czytając uważnie twoje pytanie, po prostu chcesz zaktualizować tabelę B w oparciu o nowe wartości tożsamości w tabeli A.

Po zakończeniu wstawiania uruchom aktualizację...

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

Zakłada się, że kombinacja FName / LName może być używana do kluczowego dopasowania rekordów między tabelami. Jeśli tak nie jest, może być konieczne dodanie dodatkowych pól, aby zapewnić prawidłowe dopasowanie rekordów.

Jeśli nie masz alternatywnego klucza, który pozwala dopasować rekordy, to nie w ogóle ma to sens, ponieważ rekordów w tabeli B nie można odróżnić od siebie.

 5
Author: njr101,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 19:48:26

Jeśli zawsze chcesz tego zachowania, możesz umieścić after INSERT trigger na TableA, który zaktualizuje tabelę B.

 0
Author: Matt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 19:26:27

Możesz uzyskać łącząc się na numer wiersza . Jest to możliwe, ponieważ jest to tożsamość, będzie ona po prostu zwiększana w miarę dodawania elementów, które będą w kolejności, w jakiej je zaznaczasz.

 0
Author: Darren Kopp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-18 19:29:02

O ile to Rozumiem problem, który masz polega na tym, że chcesz wstawić do Tabeli A, która ma kolumnę tożsamości, i chcesz zachować tożsamość z tabeli B, która nie ma.

Aby to zrobić, musisz po prostu włączyć identity insert w tabeli A. pozwoli to zdefiniować Twoje ID na insert i tak długo, jak nie kolidują, powinieneś być w porządku. Wtedy możesz po prostu zrobić:

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

Nie wiem, jakiego DB używasz, ale dla sql server polecenie aby włączyć insert tożsamości należy:

set identity_insert A on
 0
Author: Cory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-18 08:51:41

Sugeruję użycie typu uniqueidentifier zamiast tożsamości. W tym przypadku można wygenerować ID przed wstawieniem:

update B set NewID = NEWID()

insert into A(fname,lname,id) select fname,lname,NewID from B
 0
Author: Dmitry Khalatov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-18 08:52:03