2010-10-13 11 views
5

Czy możliwe jest uzyskanie nowych wartości identyfikatora (IDENTITY) przed wstawieniem danych do tabeli?Czy możliwe jest uzyskanie nowych wartości identyfikatora (IDENTITY) przed wstawieniem danych do tabeli?

Czy można napisać coś takiego:

INSERT INTO Table1 
SELECT *GET_NEW_IDENTITY*, Field1, Field2 FROM Table2 

muszę wartości Id bo chcę wstawić dane w tabeli 1. i tuż po, dane wkładki w innej tabeli, który ma klucz obcy połączony z Tabelą 1 (z Id)

Odpowiedz

6

IDENT_CURRENT. Zwraca ostatnią wartość tożsamości wygenerowaną dla określonej tabeli lub widoku. Ostatnia wygenerowana wartość tożsamości może dotyczyć dowolnej sesji i dowolnego zakresu.

SCOPE_IDENTITY. Zwraca ostatnią wartość tożsamości wstawioną do kolumny tożsamości w tym samym zakresie. Zakres to moduł: procedura składowana, wyzwalacz, funkcja lub partia.

OUTPUT. Zwraca informacje lub wyrażenia oparte na każdym wierszu, którego dotyczy instrukcja INSERT, UPDATE, DELETE lub MERGE. [...] Klauzula OUTPUT może być przydatna do pobrania wartości tożsamości lub kolumn obliczeniowych po operacji INSERT lub UPDATE.

+2

Nigdy w żadnym wypadku nie używaj id_current do tego, NIE zwróci poprawnego wyniku, jeśli masz wielu użytkowników! Wynik jest najlepszym wyborem lub scope_identity(), jeśli twoja wersja nie obsługuje klauzuli wyjścia. – HLGEM

0

Nie, ponieważ jest to akt dodawania wiersza, który tworzy nową wartość tożsamości.

Aby zrobić to, co chcesz,

SELECT newid = @@identity FROM table 

tuż po INSERT

+0

@@ tożsamości jest bardzo niebezpieczne używać i nie będzie rzetelnie zwracać poprawnych wyników. Nie używaj go do tego celu. – HLGEM

0

dlaczego trzeba uzyskać wartość tożsamości przed wykonaniem wkładki? Po prostu wstaw wstawkę do tabeli 2, zwracając numer SCOPE_IDENTITY(), a następnie użyj wynikowej wartości identyfikatora dla wstawki do tabeli 1.

+0

Ponieważ chcę zrobić wsadowy wsad (nie wstawić rząd po rzędzie) dla perf –

+1

W takim przypadku nie, nie można tego zrobić. Trzeba uzyskać tożsamość po każdym wstawieniu wiersza, jak wskazano w jego odpowiedzi jako @smirkingman. –

+0

@AJ: Ok, dzięki –

2

możesz również użyć instrukcji insert, aby zwrócić nowo wstawioną wartość do późniejszego użycia. na przykład:

create table demo(Id int identity primary key, data varchar(10)) 
go 
insert into demo(data) output inserted.Id values('something') 
0

To tylko szybkie demo. Możesz użyć nowego identyfikatora do wstawienia w celu aktualizacji, wstawienia do innej tabeli, zapytania itp. W inny sposób. Mając nadzieję, że nie wkładać błędy w skrypcie podczas formatowania, edycja po

-- run [1] before this script once to have environment 

--create temporary table once if not dropped after 
-- really only ID field is needed, the others are for illustration 
create table #temp_id (Id int, d1 int, d2 int) 

select * from Table2;-- this is read-only, filled once here source 
select * from Table1;--interesting for following runs 

insert into Table1 
    OUTPUT INSERTED.id 
    -- really only ID is needed, the rest is for illustration 
    , inserted.d1, inserted.d2 INTO #temp_id 
select field1, field2, null-- null to be merged later 
-- or inserted/updated into another table 
    from Table2; 

select * from Table1; 
select * from #temp_id; 


MERGE Table1 AS TARGET 
    USING #temp_id AS SOURCE 
     ON (TARGET.id = SOURCE.id) 
    WHEN MATCHED 
--AND OR are redundant if Table1.ID is PK  
    THEN 
    UPDATE SET TARGET.IDnew = SOURCE.id; 


select * from Table1; 


--drop table #temp_id 
--drop table table1 
--drop table table2 

[1]
odtwarzając tabele z pytaniem i wypełnienie danych

create table Table1(Id int identity primary key, d1 int, d2 int, IDnew int) 
create table Table2(field1 int, field2 int) 
insert into table2 values(111,222) 
insert into table2 values(333,444)