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) 
Powiązane problemy