SQL Server - вяртае значэнне пасля INSERT

Я спрабую атрымаць ключ-значэнне назад пасля INSERT-выпіскі. прыклад: У мяне ёсць табліца з імем атрыбутаў і ід. Ідэнтыфікатар ўяўляе сабой згенераванае значэнне.

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

Цяпер я хачу, каб атрымаць ідэнтыфікатар назад у тым жа кроку. Як гэта робіцца?

Мы выкарыстоўваем Microsoft SQL Server 2008.

211
дададзена аўтар Vladimir Vagaytsev, крыніца
Я знайшоў адказ КАРЫСНЫЯ тут: [PreparedStatement-са сцвярджэннем зваротнага згенераваных-ключы] [1] [1]: stackoverflow.com/questions/4224228/…
дададзена аўтар Lars Ladegaard, крыніца

10 адказы

Няма неабходнасці ў асобным SELECT ...

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

Гэта працуе для нетождества слупкоў (напрыклад, GUIDs) таксама

343
дададзена
Эй, ты даў на SO/SE? Ваш апошні пост быў на ад Dec'14. Так што толькі каментары.
дададзена аўтар abatishchev, крыніца
@JonnyLeeds: вы не можаце зрабіць гэта ў зменную (калі зменная табліца). OUTPUT ідзе да кліента або табліцы
дададзена аўтар gbn, крыніца
@hajikelist: гэта даволі крайні выпадак, SET NCOOUNT ON ў трыгер звычайна дапамагае. См stackoverflow.com/questions/1483732/set-nocount-on-usage
дададзена аўтар gbn, крыніца
Ніколі не выкарыстоўвайце @@ IDENTITY. SCOPE_IDENTITY, так, але ніколі не @@ IDENTITY. гэта ненадзейна
дададзена аўтар gbn, крыніца
Вы маглі б распрацаваць трохі? Дзе Выхад ісці ў гэтым прыкладзе? Дакументацыя прыведзены толькі прыклады для табліц (выкарыстоўваючы выхад ... у ). У ідэале я хацеў бы проста быць у стане перадаць яго ў зменную
дададзена аўтар Jonny Leeds, крыніца
Вы можаце выкарыстоўваць @@ IDENTITY і іншыя, а таксама. І парадак мае значэнне становішча! (Даведаўся цвёрды шлях ..)
дададзена аўтар Z. Khullah, крыніца
@gbn я не згодзен - Трыгеры надзвычай распаўсюджаныя. Я не ўпэўнены, што ўстаноўка NOCOUNT ўсталёўвае, што, калі ласка, прачытайце гэты пост MSDN для больш глыбокага тлумачэння.
дададзена аўтар hajikelist, крыніца
На жаль, вы не можаце спадзявацца на гэта, так як даданне трыгера ў табліцу зломіць вашыя заявы! Re:
дададзена аўтар hajikelist, крыніца

Выкарыстоўвайце scope_identity() , каб атрымаць новае значэнне ідэнтыфікатара

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

SELECT SCOPE_IDENTITY()

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

126
дададзена
@ Liho1eye - ОП называюць імем слупка ідэнтычнасці як ID , так што так.
дададзена аўтар Curt, крыніца
пры ўмове, ідэнтыфікатар гэта тоеснасць
дададзена аўтар Ilia G, крыніца
На большай сістэмы, што, калі многія SQL Бегалі адначасова? Ці будзе ён вярнуць апошні устаўлены ідэнтыфікатар для кожнага запыту?
дададзена аўтар Shiv, крыніца
@Shiv «SCOPE_IDENTITY вяртае значэння, устаўленыя толькі ў межах бягучай вобласці»
дададзена аўтар goodies4uall, крыніца
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

З'яўляецца бяспечная стаўка, бо існуе вядомая праблема з выхадам Пункта канфліктам на сталах з трыгерамі. Робіць гэта вельмі ненадзейныя, так як нават калі табліца ў цяперашні час няма ніякіх трыгераў - хтосьці дадаўшы адзін ўніз лінію зламаецца прыкладання. Time Bomb роду паводзіны.

См артыкул MSDN для больш глыбокага тлумачэнні:

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

30
дададзена
@hajikelist Мы ўсе спадчыну, але рызыка трыгераў Месінга ВЫХОДНОЙ ўверх нізкі, ён прымае ўсе усталёўваецца NOCOUNT на. Калі хто-то дадае трыгер, то яны павінны ведаць, як яго код (азначае, што вы павінны кантраляваць у асноўным), ці вы павінны навучаць сваіх распрацоўшчыкаў .. У нейкі момант, вы будзеце вымушаныя міграваць, калі гэтая версія SQL больш не падтрымліваецца і г.д. так трыгеры не будзе выклікаць ResultSet. Безадносна, гэта не самы лепшы адказ, таму што калі ў вас ёсць ЗАМЕСТ ініцыюе SCOPE_IDENTITY можа не працаваць ( stackoverflow.com/questions/908257/… )
дададзена аўтар gbn, крыніца
Толькі калі вы не дадасце SET NOCOUNT ON у трыгераў. Таксама гл
дададзена аўтар gbn, крыніца
гэта не варыянт для нашых старых асяроддзяў @gbn
дададзена аўтар hajikelist, крыніца
@gbn - Я проста хацеў, каб пазбегнуць дурных рэчаў, як гэта. Я не буду расказваць усе мае распрацоўшчыкі, «Не забудзьцеся дадаць" не парушу дадатак аб "у кожным трыгераў.» - Вы можаце захаваць яго. Сцэнар «замест» значна больш краю выпадку ім.
дададзена аўтар hajikelist, крыніца

Entity Framework выконвае нешта падобнае на адказ ГБН у:

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

Вынікі выходных захоўваюцца ў зменнай часовай табліцы, а затым выбіраецца назад кліенту. Павінны быць у курсе Gotcha:

<�Р> ўстаўкі могуць генераваць больш аднаго радка, так што пераменная можа ўтрымліваць больш аднаго радка, так што вы можаце быць вернутыя больш аднаго ID </р>

Я паняцця не маю, чаму EF бы ўнутранае злучэнне эфемерную табліцу назад да рэальнай табліцы (пры якіх абставінах б два не супадаюць).

Але гэта тое, што робіць EF.

SQL Server 2008 або больш позняя версія толькі. Калі гэта 2005 г., то вам не пашанцавала.

12
дададзена

@@ IDENTITY Ці сістэмная функцыя, якая вяртае апошняе ўстаўленае значэнне ідэнтыфікатара.

7
дададзена
Ёсць пракансультаваць супраць калі-небудзь з дапамогай @@ IDENTITY - гэта не дакладная (занадта шырокі) значна менш потокобезопасной - калі ласка, глядзіце @ адказ Курта аб scope_identity ().
дададзена аўтар zanlok, крыніца

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
дададзена
ды, ніколі не выкарыстоўваць яго. яна не працуе добра Alwayse: X
дададзена аўтар H.Ghassami, крыніца
Ніколі не выкарыстоўвайце @@ IDENTITY: гэта не сфера бяспечная: Трыгеры і г.д. афект яго.
дададзена аўтар gbn, крыніца

Вы можаце выкарыстоўваць SCOPE_IDENTITY, каб выбраць ідэнтыфікатар радкі, якую толькі што ўставілі ў зменную, то проста выбраць тое, што слупкі вы хочаце з гэтай табліцы, дзе ID = асобу вы атрымалі ад scope_identity

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

3
дададзена

* 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.

Пасля дадання радкі, полі не даступна, калі правайдэр не зададзены як <�моцнага> першага параметра </моцнага> ў радку падключэння. Калі правайдэр ў любым месцы ў радку злучэння, за выключэннем у якасці першага параметра, зноў устаўленыя поля радкі не даступныя. Калі мы перамясцілі пастаўшчык да першага параметры, поле радкі чароўным чынам з'явілася.

2
дададзена
Вам трэба адрэдагаваць і палепшыць свой адказ. Гэта ў цяперашні час шумна і ня трапляецца як годны адказ або нават спроба
дададзена аўтар James, крыніца
Многія карыстальнікі, верагодна, прыйшлі на гэтую старонку, таму што яны не маюць сапраўдныя поля для ідэнтыфікацыі радкі дададзеным. Такія паводзіны мы знайшлі (што проста змяніўшы парадак прытрымлівання параметраў у радку падключэння дазваляе атрымаць доступ да зноў дададзенаму шэрагу адразу) настолькі дзіўна, што я думаў, што ён заслугоўвае згадак у шапках, тым больш, што гэта вельмі верагодна, выправіць прычыну, па якой людзі хочуць новы ID радкі і іншыя поля гэтага радка. Проста паставіўшы пастаўшчыка ў якасці першага параметра, то праблема знікае.
дададзена аўтар David Guidos, крыніца
Што менавіта вы маеце на ўвазе пад «шумнымі»? Вы павінны растлумачыць сваю скаргу. Гэта прыкладна так жа проста, як гэта можа быць. Калі змяніць парадак параметраў у радку падключэння, гэта можа паўплываць ці наяўныя дадзеныя радкі пасля ўстаўкі.
дададзена аўтар David Guidos, крыніца
Не маглі б вы расказаць нам, як гэты каментар адказы/мае дачыненне да пытання, якое было зададзена? Я не адчуваю, што гэта заслугоўвае каўпачкоў/тлустым шрыфтам. Калі ваш адказ лічыцца карысным, карыстальнікі будуць галасаваць яго.
дададзена аўтар n__o, крыніца

Вы можаце дадаць абранае заяву даданнем заяве. Integer Мінт = Уставіць у table1 (Fname) значэнні ( 'Fred'); Выберыце scope_identity (); Гэта будзе вяртаць значэнне ідэнтычнасці пры выкананні скейлера.

0
дададзена

Гэта, як я выкарыстоўваю OUTPUT ўставілі, пры ўстаўцы ў табліцу, якая выкарыстоўвае ідэнтыфікатар ў якасці слупка ідэнтыфікатараў у SQL Server:

'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
дададзена