SQL Server - INSERT'den sonra dönüş değeri

Bir INSERT ifadesinden sonra anahtar değerini geri almaya çalışıyorum. Örnek: Adı ve kimliği olan bir tablom var. id üretilen bir değerdir.

    INSERT INTO table (name) VALUES('bob');

Şimdi kimliği aynı adımda geri almak istiyorum. Bu nasıl yapılır?

Microsoft SQL Server 2008 kullanıyoruz.

211
Burada yararlı bir cevap buldum: [deyim-dönüşü ile üretilmiş-anahtarlarla hazırlananlar] [1] [1]: stackoverflow.com/questions/4224228/…
katma yazar Lars Ladegaard, kaynak

10 cevap

Ayrı bir SELECT gerek yok ...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

Bu, IDENTITY olmayan sütunlar için de (GUID'ler gibi) çalışır.

343
katma
Hey, SO/SE’yi verdin mi? Son mesajınız 14 Aralık'ta yayınlandı. O zamandan beri sadece yorumlar.
katma yazar abatishchev, kaynak
@JonnyLeeds: Bunu bir değişkene yapamazsınız (tablo değişkeni yoksa). ÇIKIŞ müşteri veya bir masaya gider
katma yazar gbn, kaynak
@hajikelist: Bu oldukça kenar bir durum, tetikleyicide SET NCOOUNT ON genellikle yardımcı olur. stackoverflow.com/questions/1483732/set-nocount-on-usage adresine bakın.
katma yazar gbn, kaynak
Asla @@ KİMLİK kullanmayın. SCOPE_IDENTITY, evet, fakat asla @@ IDENTITY. Güvenilmez
katma yazar gbn, kaynak
biraz detay verebilir misiniz Çıktı bu örnekte nereye gider? Dokümantasyon yalnızca tablolar için örnekler gösterir (çıktı kullanarak ... ). İdeal olarak, onu sadece bir değişkene aktarabilmeyi isterdim
katma yazar Jonny Leeds, kaynak
@@ IDENTITY ve diğerlerini de kullanabilirsiniz. Ve fıkra sırası önemli! (zor yoldan öğrendim ..)
katma yazar Z. Khullah, kaynak
@gbn Ben katılmıyorum - tetikleyiciler son derece yaygındır. NOCOUNT ayarının bunu düzelttiğinden emin değilim, lütfen daha derin bir açıklama için bu msdn gönderisini okuyun.
katma yazar hajikelist, kaynak
Ne yazık ki, buna güvenemezsiniz, çünkü tabloya bir tetikleyici eklemek ifadelerinizi kıracak! re: blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/…
katma yazar hajikelist, kaynak

Yeni kimlik değerini almak için SCOPE_IDENTITY() tuşunu kullanın

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/library/ms190315.aspx

126
katma
@ liho1eye - OP kimlik sütunu adına id adını verdi, bu yüzden evet.
katma yazar Curt, kaynak
id kimliğini varsayarsak
katma yazar Ilia G, kaynak
Daha büyük sistemde, eğer aynı anda birçok sql çalışıyorsa? En son eklenen kimliği her talebe döndürür mü?
katma yazar Shiv, kaynak
@Shiv "SCOPE_IDENTITY yalnızca geçerli kapsam içinde eklenen değerleri döndürür"
katma yazar goodies4uall, kaynak
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

OUTPUT Cümlesinin tetiklemeli tablolarda çakışmasıyla ilgili bilinen bir sorun olduğundan en güvenli bahis budur. Tablonuzda şu anda herhangi bir tetikleyici olmasa bile, bu durumu oldukça güvenilmez hale getirir; Saatli bomba tür davranış.

Daha derin açıklama için msdn makalesine bakınız:

http : //blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

30
katma
@hajikelist Hepimizin mirası var, ancak ÇIKIŞ'ı tıkayan tetikleyicilerin riski düşük, alması gereken her şey açık. Birisi bir tetikleyici ekliyorsa, bunun nasıl kodlanacağını bilmesi gerekir (temelde kontrolün sizde olduğu anlamına gelir) veya geliştiricilerinizi eğitmeniz gerekir. Bir noktada, bu SQL sürümü artık olmadığı zaman göç etmek zorunda kalacaksınız Desteklenen vb. böylece tetikleyiciler bir sonuç setine neden olmaz. Her neyse, en iyi cevap bu değil çünkü INSTEAD OF varsa SCOPE_IDENTITY çalışmayabilir ( stackoverflow.com/questions/908257/… )
katma yazar gbn, kaynak
Yalnızca tetikleyicilere SET NOCOUNT ON eklemezseniz. Ayrıca bkz. docs.microsoft.com/en-us/sql/database-engine/configure-windo‌ ws/& hellip;
katma yazar gbn, kaynak
bu bizim eski ortamlarımız için bir seçenek değildir @gbn
katma yazar hajikelist, kaynak
@gbn - Sadece böyle aptalca şeylerden kaçınmayı severim. Tüm geliştiricilerime, "Her tetikleyicide" uygulama ifademi kırma "seçeneğini eklemeyi unutmayın." - sende kalabilir. "Bunun yerine" senaryosu, bir imo senaryosundan çok daha fazla.
katma yazar hajikelist, kaynak

Varlık Çerçevesi, gbn'in cevabına benzer bir şey gerçekleştirir:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

Çıktı sonuçları geçici bir tablo değişkeninde saklanır ve ardından müşteriye geri seçilir. Gotcha'nın farkında olmalıyız:

ekler birden fazla satır oluşturabilir, böylece değişken birden fazla satır tutabilir, böylece birden fazla ID

döndürülebilir

EF'in neden geçici masaya gerçek masaya katılacağı hakkında hiçbir fikrim yok (hangi şartlar altında hangi eşleşme olmazdı).

Ama EF böyle yapar.

SQL Server 2008 veya sadece daha yeni. Eğer 2005 ise, o zaman şansın tükenir.

12
katma

@@ KİMLİK Son eklenen kimliğin değerini döndüren bir sistem işlevidir.

7
katma
Hiç @@ IDENTITY kullanmamaya karşı tavsiyede bulunmalısınız - bu doğru (çok geniş değil) çok daha az güvenli değildir - lütfen @ Curt'in SCOPE_IDENTITY() hakkındaki cevabına bakınız.
katma yazar zanlok, kaynak

After doing an insert into a table with an identity column, you can reference @@IDENTITY to get the value: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx

5
katma
evet, asla kullanmayın. çok iyi çalışmıyor: X
katma yazar H.Ghassami, kaynak
Asla @@ KİMLİK kullanmayın: kapsamı güvenli değil: tetikleyiciler vb. Onu etkiler.
katma yazar gbn, kaynak

Bir değişkene yeni eklediğiniz satırın kimliğini seçmek için kapsam_adesini kullanın, daha sonra bu tablodan istediğiniz sütunları seçin, burada id = kapsam_adesinden aldığınız kimlik

See here for the MSDN info http://msdn.microsoft.com/en-us/library/ms190315.aspx

3
katma

* Parameter order in the connection string is sometimes important. * The Provider parameter's location can break the recordset cursor after adding a row. We saw this behavior with the SQLOLEDB provider.

Bir satır eklendikten sonra, satır alanları kullanılamaz, UNLESS Sağlayıcı bağlantı dizesinde ilk parametre olarak belirtilir. Sağlayıcı, ilk parametre dışında bağlantı dizesinde herhangi bir yerdeyse, yeni eklenen satır alanları kullanılamaz. Sağlayıcıyı ilk parametreye taşıdığımızda, satır alanları sihirli bir şekilde ortaya çıktı.

2
katma
Cevabınızı düzenlemeniz ve geliştirmeniz gerekir. Şu anda gürültülü ve düzgün bir cevap ya da bir girişim olarak rastlamıyor
katma yazar James, kaynak
Çok sayıda kullanıcı muhtemelen bu sayfaya geldi, çünkü yeni eklenen satırı tanımlayacak geçerli alanları yoktu. Bulduğumuz bu davranış (sadece bağlantı dizesindeki parametrelerin sırasının değiştirilmesinin hemen yeni eklenen satıra erişime izin vermesi) o kadar tuhaf ki, özellikle insanların yeni istemeyi istemesinin nedenini büyük olasılıkla çözeceğinden büyük harflerle bahsetmeyi hak ettiğini düşündüm. satır kimliği ve bu satırın diğer alanları. Sağlayıcıyı ilk parametre olarak koyarak, sorun ortadan kalkar.
katma yazar David Guidos, kaynak
"Gürültülü" derken tam olarak ne demek istiyorsun? Şikayetinizi açıklamanız gerekir. Olabildiğince basit. Bağlantı dizginizdeki parametrelerin sırasını değiştirirseniz, satır verilerinin eklemeden sonra kullanılabilir olup olmadığını etkileyebilir.
katma yazar David Guidos, kaynak
Bize bu yorumun sorulan soru ile nasıl cevap verdiğini/alakalı olduğunu söyler misiniz? Büyük harf/kalın hak ettiğini sanmıyorum. Cevabınız yardımcı sayılırsa, kullanıcılar oy kullanır.
katma yazar n__o, kaynak

Select ifadesini insert ifadenize ekleyebilirsiniz. Tamsayı myInt = Table1 (FName) değerlerine ('Fred') ekleyin; Scope_Identity (); Bu, ölçekleyici çalıştırıldığında kimliğin değerini döndürür.

0
katma

SQL Server'da kimlik sütunu olarak kimlik kullanan bir tabloya eklerken OUTPUT INSERTED yöntemini şu şekilde kullanırım:

'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)
0
katma