ඇතුළත් කළ පේළියේ අනන්‍යතාවය ලබා ගැනීමට හොඳම ක්‍රමය කුමක්ද?


1138

IDENTITYඇතුළත් කළ පේළිය ලබා ගැනීමට හොඳම ක්‍රමය කුමක්ද?

මම දන්නවා @@IDENTITY හා IDENT_CURRENTහා SCOPE_IDENTITYනමුත්, එක් එක් අනුයුක්ත වාසි සහ අවාසි තේරෙන්නේ නැහැ.

කරුණාකර යමෙකුට වෙනස්කම් පැහැදිලි කළ හැකිද?


7
INSERT INTO Table1(fields...) OUTPUT INSERTED.id VALUES (...), හෝ පැරණි ක්‍රමය: INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();ExecuteScalar () භාවිතයෙන් ඔබට එය c # වලින් ලබා ගත හැකිය.
එස්.සර්පූෂන්

4
එය අනෙක් පිළිතුරු වලට වඩා හොඳ වන්නේ කෙසේද? (එසේම - ඔබ මෙය අදහස් දැක්වීමක් වෙනුවට පිළිතුරක් ලෙස පළ නොකරන්නේ ඇයි). කරුණාකර සම්පූර්ණ පිළිතුරක් ලියන්න (සහ මෙය පළ කරන ලද ඒවාට වඩා හොඳ විකල්පයක් වන්නේ මන්දැයි පැහැදිලි කරන්න - අනුවාදය විශේෂිත නම්, එසේ කියන්න).
Oded

එය කෙටි සාරාංශයක් මෙනි. ; D පිළිගත් පිළිතුරෙහි OUTPUT වගන්තියේ වාක්‍ය ඛණ්ඩය සඳහන් නොවන අතර නියැදියක් නොමැත. එසේම වෙනත් තනතුරු වල සාම්පල එතරම් පිරිසිදු නැත ...
එස්.සර්පූෂාන්

2
a සයිඩ්සර්පූෂාන් - ඉන්පසු එය සංස්කරණය කරන්න. ඔබට එය කළ හැකිය, ඔබ දන්නවාද? එම පිළිතුර පළ කරන විට බලන්න? එය OUTPUTSQL සේවාදායකයේ වගන්තියට පෙරාතුව වේ.
Oded

Answers:


1464
  • @@IDENTITYවත්මන් සැසියේ ඕනෑම වගුවක් සඳහා ජනනය කරන ලද අවසාන අනන්‍යතා අගය, සියලු විෂය පථයන් හරහා ලබා දෙයි. ඔබ මෙහි පරෙස්සම් විය යුතුය , මන්ද එය විෂය පථයන් හරහා ය. ඔබගේ වර්තමාන ප්‍රකාශය වෙනුවට ප්‍රේරකයකින් ඔබට වටිනාකමක් ලබා ගත හැකිය.

  • SCOPE_IDENTITY()වත්මන් සැසියේ ඕනෑම වගුවක් සඳහා ජනනය කරන ලද අවසාන අනන්‍යතා අගය සහ වත්මන් විෂය පථය ලබා දෙයි. සාමාන්යයෙන් ඔබට භාවිතා කිරීමට අවශ්ය දේ .

  • IDENT_CURRENT('tableName')ඕනෑම සැසියක සහ ඕනෑම විෂය පථයක නිශ්චිත වගුවක් සඳහා ජනනය කරන ලද අවසාන අනන්‍යතා අගය ලබා දෙයි. ඉහත දෙක ඔබට අවශ්‍ය දේ නොවන්නේ නම් ( ඉතා කලාතුරකිනි ) ඔබට වටිනාකම අවශ්‍ය කුමන වගුවෙන්ද යන්න සඳහන් කිරීමට මෙය ඔබට ඉඩ දෙයි . එසේම, @ ගයි ස්ටාර්බක් සඳහන් කළ පරිදි, "ඔබ වාර්තාවක් ඇතුළත් නොකළ වගුවක් සඳහා වත්මන් හැඳුනුම් වටිනාකම ලබා ගැනීමට අවශ්‍ය නම් ඔබට මෙය භාවිතා කළ හැකිය."

  • මෙම OUTPUTවගන්තිය පිළිබඳ INSERTප්රකාශයක් ඔබ ඇතුළත් කළ බව එම ප්රකාශය හරහා සෑම පේළිය ප්රවේශ ඉඩ ඇත. එය නිශ්චිත ප්‍රකාශයට විෂය පථය කර ඇති බැවින්, එය ඉහත සඳහන් අනෙක් කාර්යයන්ට වඩා සරල ය. කෙසේ වෙතත්, එය තව ටිකක් වාචිකය (ඔබට වගු විචල්‍ය / තාවකාලික වගුවකට ඇතුළු කර එය විමසිය යුතුය) තවද එය ප්‍රකාශය පෙරළා දැමූ දෝෂ සහිත අවස්ථාවකදී පවා ප්‍රති results ල ලබා දේ. ඔබේ විමසුම සමාන්තර ක්‍රියාත්මක කිරීමේ සැලැස්මක් භාවිතා කරන්නේ නම් , අනන්‍යතාවය ලබා ගැනීම සඳහා සහතික කළ හැකි එකම ක්‍රමය මෙයයි (සමාන්තරකරණය අක්‍රිය කිරීම කෙටි). කෙසේ වෙතත්, එය ප්‍රේරකයට පෙර ක්‍රියාත්මක වන අතර ප්‍රේරක ජනනය කළ අගයන් ආපසු ලබා දීමට භාවිතා කළ නොහැක.


50
SCOPE_IDENTITY () සමඟ දන්නා දෝෂය වැරදි අගයන් ලබා දෙයි: blog.sqlauthority.com/2009/03/24/… අවට ඇති කාර්යය නම් බහු ප්‍රොසෙසර සමාන්තර සැලැස්මක් තුළ INSERT ධාවනය නොකිරීම හෝ OUTPUT වගන්තිය භාවිතා කිරීම
KM.

4
මට 'අනන්‍යතාවය' අවශ්‍ය වූ සෑම අවස්ථාවකම පාහේ, මා විසින් ඇතුළත් කළ වාර්තාවේ (ය) යතුර දැන ගැනීමට මට අවශ්‍ය වී තිබේ. එය ඔබගේ තත්වය නම්, ඔබට OUTPUT වගන්තිය භාවිතා කිරීමට අවශ්‍යය. ඔබට වෙනත් දෙයක් අවශ්‍ය නම්, bdukes ප්‍රතිචාරය කියවා තේරුම් ගැනීමට උත්සාහ කරන්න.
ජෙරී

4
ප්‍රති with outputල ගබඩා කිරීමට සහ විමසීමට ඔබ සමඟ තාවකාලික වගුවක් සෑදිය යුතු නැත. intoප්‍රතිදාන වගන්තියේ කොටස අතහැර දමන්න, එවිට එය ප්‍රති .ල කට්ටලයකට ප්‍රතිදානය කරනු ඇත.
spb

99
අන් අය භීතියෙන් බේරා ගැනීම සඳහා, ඉහත සඳහන් දෝෂය SQL Server 2008 R2 Service Pack 1 සඳහා සමුච්චිත යාවත්කාලීන 5 හි සවි කර ඇත.
GaTechThomas

1
iniico, මම හිතන්නේ නිර්දේශය තිබු ආකාරයටමයි, එනම් OUTPUTඔබ ප්‍රේරක භාවිතා නොකරන අතර දෝෂ හසුරුවන තාක් කල් එය “හොඳම” වේ, නමුත් SCOPE_IDENTITYසරලම හා ඉතා කලාතුරකින් ගැටළු ඇති
bdukes

182

ඇතුළත් කළ හැඳුනුම්පත නැවත ලබා ගැනීමේ ආරක්ෂිතම හා නිවැරදි ක්‍රමය වනුයේ ප්‍රතිදාන වගන්තිය භාවිතා කරනු ඇතැයි මම විශ්වාස කරමි.

උදාහරණයක් ලෙස (පහත දැක්වෙන කරුණු වලින් ගනු ලැබේ MSDN ලිපියෙන් ගත්)

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
                           Name varchar(50),
                           ModifiedDate datetime);
INSERT Production.ScrapReason
    OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
        INTO @MyTableVar
VALUES (N'Operator error', GETDATE());

--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate 
FROM Production.ScrapReason;
GO

3
ඔව්, මෙය ඉදිරියට යන නිවැරදි ක්‍රමයයි, ඔබ SQL Server 2008 හි නොමැති නම් අනෙක් ඒවායින් එකක් පමණක් භාවිතා කරන්න (අපි 2005 මඟ
හැරියෙමු,

1
@HLGEM SQL Server 2005 සඳහා MSDN පිටුවක් OUTPUTඇත , එබැවින් එය SQL Server 2000 සහ ඊට පෙර නැති බව
පෙනේ

6
woohoo! පිටත ක්ලවුස් පාෂාණ :) එය මගේ වර්තමාන කාර්යය සරල කරනු ඇත. ඒ ප්‍රකාශය කලින් දැනගෙන හිටියේ නැහැ. ස්තූතියි යාලුවනේ!
ස්විස්කෝඩර්

8
ඇතුළත් කළ හැඳුනුම්පත ලබා ගැනීම සඳහා සැබවින්ම සංක්ෂිප්ත උදාහරණයක් සඳහා, බලන්න: stackoverflow.com/a/10999467/2003325
ලූක්

OUTPUT සමඟ ඔබ INTO භාවිතා කිරීම හොඳ අදහසකි. බලන්න: blogs.msdn.microsoft.com/sqlprogrammability/2008/07/11/… (මෙහි අදහස් දැක්වීමකින්: stackoverflow.com/questions/7917695/… )
shlgug

113

මම කියන්නේ අනිත් කොල්ලන්ට වගේමයි, ඒ නිසා හැමෝම නිවැරදියි, මම උත්සාහ කරන්නේ එය වඩාත් පැහැදිලි කිරීමටයි.

@@IDENTITY ඔබේ සේවාදායකයාගේ සම්බන්ධතාවය මඟින් දත්ත ගබඩාවට ඇතුළත් කළ අවසන් දෙයෙහි හැඳුනුම්පත නැවත ලබා දෙයි.
බොහෝ විට මෙය හොඳින් ක්‍රියාත්මක වේ, නමුත් සමහර විට ප්‍රේරකයක් ගොස් ඔබ නොදන්නා නව පේළියක් ඇතුල් කරනු ඇත, ඔබට අවශ්‍ය පේළිය වෙනුවට මෙම නව පේළියෙන් හැඳුනුම්පත ලැබෙනු ඇත.

SCOPE_IDENTITY()මෙම ගැටළුව විසඳයි. එය ඔබ එවූ SQL කේතයේ අවසන් වරට ඇතුළත් කළ හැඳුනුම්පත ලබා දෙයි දත්ත ගබඩාවට . ප්‍රේරක ගොස් අමතර පේළි නිර්මාණය කරන්නේ නම්, ඒවා වැරදි අගයක් ආපසු ලබා නොදෙනු ඇත. හුරේ

IDENT_CURRENTඕනෑම අයෙකු විසින් ඇතුළත් කළ අවසන් හැඳුනුම්පත ආපසු ලබා දෙයි. අනපේක්ෂිත වේලාවක වෙනත් පේළියක් ඇතුළු කිරීමට වෙනත් යෙදුමක් සිදුවුවහොත්, ඔබේ පේළිය වෙනුවට එම පේළියේ හැඳුනුම්පත ඔබට ලැබෙනු ඇත.

ඔබට එය ආරක්ෂිතව සෙල්ලම් කිරීමට අවශ්‍ය නම්, සෑම විටම භාවිතා කරන්න SCOPE_IDENTITY(). ඔබ පසුව රැඳී සිටිමින් @@IDENTITYයමෙකු පසුව ප්‍රේරකයක් එක් කිරීමට තීරණය කළහොත් , ඔබගේ සියලු කේත කැඩී යනු ඇත.


64

අලුතින් ඇතුළත් කළ පේළියක අනන්‍යතාවය ලබා ගැනීම සඳහා හොඳම (කියවන්න: ආරක්ෂිත) ක්‍රමය වන්නේ outputවගන්තිය භාවිතා කිරීමෙනි :

create table TableWithIdentity
           ( IdentityColumnName int identity(1, 1) not null primary key,
             ... )

-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )

insert TableWithIdentity
     ( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
     ( ... )

select @IdentityValue = (select ID from @IdentityOutput)

5
SQL සේවාදායක පොකුරුකරණය ඉහළ උපයෝජ්‍යතා අංගයක් වන අතර සමාන්තරකරණයට කිසිදු බලපෑමක් නැත. තනි පේළි ඇතුළත් කිරීම් (වඩාත් පොදු අවස්ථාව scope_identity()) කෙසේ හෝ සමාන්තර සැලසුම් ලබා ගැනීම ඉතා අසාමාන්‍යය . මෙම පිළිතුර මෙම පිළිතුරට වසරකට පෙර නිවැරදි කරන ලදි.
මාටින් ස්මිත්

සමාන්තරකරණයෙන් ඔබ අදහස් කරන්නේ කුමක්ද?
user1451111

Art මාටින් ස්මිත් සේවාදායකයා තම සේවාදායක පොකුරේ අක්‍රීයව මෙම ගැටළුව නිරාකරණය කිරීම සඳහා CU ස්ථාපනය කිරීමට ඉඩ දුන්නේ නැත (විහිළුවක් නොවේ), එබැවින් එකම විසඳුම වූයේ outputඒ වෙනුවට භාවිතා කිරීමට ඇති සියලුම SQL නැවත ලිවීමයි scope_identity(). පිළිතුරෙහි පොකුරුකරණය පිළිබඳ FUD ඉවත් කර ඇත.
ඉයන් කෙම්ප්

1
ස්තූතියි, මට සොයා ගැනීමට හැකි වූ එකම උදාහරණය මෙය විචල්‍යයක ප්‍රතිදානයේ අගය ප්‍රතිදානය වෙනුවට භාවිතා කරන්නේ කෙසේද යන්න පෙන්වයි.
ෂෝන් රේ

26

එකතු කරන්න

SELECT CAST(scope_identity() AS int);

ඔබගේ ඇතුළත් කිරීමේ SQL ප්‍රකාශයේ අවසානය දක්වා

NewId = command.ExecuteScalar()

එය ලබා ගනී.


22

ඔබ ආයතන රාමුව භාවිතා කරන විට, එය අභ්‍යන්තරව OUTPUTඅළුතින් ඇතුළු කරන ලද හැඳුනුම්පත් අගය ආපසු ලබා දීමට තාක්ෂණය භාවිතා කරයි

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');

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

ප්‍රතිදාන ප්‍රති results ල තාවකාලික වගු විචල්‍යයක ගබඩා කර ඇති අතර, නැවත මේසයට සම්බන්ධ වී පේළි අගය මේසයෙන් පිටතට ගෙන එයි.

සටහන: ඊඑෆ් අභ්‍යන්තරික කාලානුරූපී වගුවට නැවත සැබෑ වගුවට සම්බන්ධ වන්නේ මන්දැයි මා දන්නේ නැත (කුමන තත්වයන් යටතේ දෙදෙනා නොගැලපේ).

නමුත් ඊඑෆ් කරන්නේ එයයි.

මෙම තාක්ෂණය ( OUTPUT) ලබා ගත හැක්කේ SQL Server 2008 හෝ නවතම ඒවා මත පමණි.

සංස්කරණය කරන්න - සම්බන්ධ වීමට හේතුව

හුදෙක් OUTPUTඅගයන් භාවිතා කරනවාට වඩා, ආයතන රාමුව මුල් වගුවට සම්බන්ධ වීමට හේතුව, rowversionඅලුතින් ඇතුළත් කළ පේළියක් ලබා ගැනීම සඳහා ඊඑෆ් ද මෙම තාක්ෂණය භාවිතා කරන බැවිනි .

ඔබ විසින් ඔබගේ ආයතනයක් රාමුව ආකෘති සර්ව සුභවාදී සමගාමී භාවිතා කළ හැකි භාවිතා Timestampවිශේෂණය: 🕗

public class TurboEncabulator
{
   public String StatorSlots)

   [Timestamp]
   public byte[] RowVersion { get; set; }
}

ඔබ මෙය කරන විට, ආයතන රාමුවට rowversionඅලුතින් ඇතුළත් කළ පේළිය අවශ්‍ය වේ:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');

SELECT t.[TurboEncabulatorID], t.[RowVersion]
FROM @generated_keys AS g 
   JOIN dbo.TurboEncabulators AS t 
   ON g.Id = t.TurboEncabulatorID 
WHERE @@ROWCOUNT > 0

මෙය ලබා ගැනීම සඳහා Timetsampඔබට වගන්තියක් භාවිතා කළ නොහැකOUTPUT .

එයට හේතුව මේසය මත ප්‍රේරකයක් තිබේ නම්, Timestampඔබ පිටවන ඕනෑම දෙයක් වැරදියි:

  • ආරම්භක ඇතුළු කිරීම. කාලරාමුව: 1
  • OUTPUT වගන්තිය මඟින් කාලරාමුව ප්‍රතිදානය කරයි: 1
  • ප්‍රේරකය පේළිය වෙනස් කරයි. කාලරාමුව: 2

ඔබ මේසය මත ප්‍රේරකයක් ඇත්නම් ආපසු ලබා දුන් කාලරාමුව කිසි විටෙකත් නිවැරදි නොවේ. එබැවින් ඔබ වෙනම භාවිතා කළ යුතුයSELECT .

ඔබ වැරදි පේළියකට ගොදුරු වීමට කැමති වුවද, වෙනමම සිදු කිරීමට ඇති අනෙක් හේතුව SELECTනම් ඔබට rowversionවගු විචල්‍යයකට පිටවිය නොහැකි වීමයි :

DECLARE @generated_keys table([Id] uniqueidentifier, [Rowversion] timestamp)

INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID, inserted.Rowversion INTO @generated_keys
VALUES('Malleable logarithmic casing');

එය කිරීමට තුන්වන හේතුව සමමිතිය සඳහා ය. UPDATEප්‍රේරකයක් සමඟ මේසයක් මත ක්‍රියා කරන විට , ඔබට වගන්තියක් භාවිතා කළ නොහැකOUTPUT . UPDATEසමඟ උත්සාහ කිරීමට OUTPUTසහාය නොදක්වන අතර එය දෝෂයක් ලබා දෙනු ඇත:

එය කළ හැකි එකම ක්‍රමය පසු විපරම් SELECTප්‍රකාශයක් පමණි:

UPDATE TurboEncabulators
SET StatorSlots = 'Lotus-O deltoid type'
WHERE ((TurboEncabulatorID = 1) AND (RowVersion = 792))

SELECT RowVersion
FROM TurboEncabulators
WHERE @@ROWCOUNT > 0 AND TurboEncabulatorID = 1

2
අඛණ්ඩතාව සහතික කිරීම සඳහා ඒවා ඒවාට ගැලපෙන බව මම සිතමි (උදා: ශුභවාදී සමගාමී ප්‍රකාරයේදී, ඔබ මේස විචල්‍යයෙන් තෝරා ගන්නා අතරතුර, යමෙකු ඇතුළු කිරීමේ පේළි ඉවත් කර තිබිය හැක). එසේම, ඔබේ ආදරෙයි TurboEncabulators:)
zaitsman

16

MSDN

@@ IDENTITY, SCOPE_IDENTITY, සහ IDENT_CURRENT සමාන කාර්යයන් වන අතර ඒවා වගුවක IDENTITY තීරුවට ඇතුළත් කළ අවසන් අගය නැවත ලබා දේ.

Session IDENTITY සහ SCOPE_IDENTITY වත්මන් සැසියේ ඕනෑම වගුවක ජනනය කරන ලද අවසාන අනන්‍යතා අගය ලබා දෙනු ඇත. කෙසේ වෙතත්, SCOPE_IDENTITY අගය ලබා දෙන්නේ වත්මන් විෂය පථය තුළ පමණි; Ent IDENTITY නිශ්චිත විෂය පථයකට සීමා නොවේ.

IDENT_CURRENT විෂය පථය සහ සැසිය අනුව සීමා නොවේ; එය නිශ්චිත වගුවකට සීමා වේ. IDENT_CURRENT ඕනෑම සැසියක සහ ඕනෑම විෂය පථයක නිශ්චිත වගුවක් සඳහා ජනනය කරන ලද අනන්‍යතා අගය ලබා දෙයි. වැඩි විස්තර සඳහා, IDENT_CURRENT බලන්න.

  • IDENT_CURRENT යනු වගුවක් තර්කයක් ලෙස ගන්නා ශ්‍රිතයකි.
  • @@ ඔබට මේසය මත ප්‍රේරකයක් ඇති විට IDENTITY ව්‍යාකූල ප්‍රති result ලබා දෙනු ඇත
  • SCOPE_IDENTITY බොහෝ විට ඔබේ වීරයා වේ.

14

@@ අනන්යතාව , ඇතුළු වත්මන් SQL සම්බන්ධතාවය භාවිතා කරමින් පසුගිය අනන්යතාවය වේ. ඔබගේ නව වාර්තාව සඳහා ඇතුළත් කර ඇති අනන්‍යතාවය අවශ්‍ය වන, ඇතුළු කළ ගබඩා කළ ක්‍රියා පටිපාටියකින් ආපසු යාමට මෙය හොඳ අගයක් වන අතර, පසුව තවත් පේළි එකතු කර ඇත්දැයි නොසලකන්න.

SCOPE_IDENTITY යනු වත්මන් SQL සම්බන්ධතාවය භාවිතයෙන් ඇතුළු කරන ලද අවසාන අනන්‍යතාවය වන අතර, වර්තමාන විෂය පථය තුළ - එනම්, ඔබේ ඇතුළත් කිරීමෙන් පසු ප්‍රේරකයක් මත පදනම්ව දෙවන හැඳුනුම්පතක් ඇතුළත් කර ඇත්නම්, එය SCOPE_IDENTITY හි පිළිබිඹු නොවනු ඇත, ඔබ සිදු කළ ඇතුළු කිරීම පමණි . අවංකවම, මට මෙය භාවිතා කිරීමට හේතුවක් නැත.

IDENT_CURRENT (වගු නාමය ) යනු සම්බන්ධතාවය හෝ විෂය පථය නොසලකා ඇතුළත් කළ අවසන් අනන්‍යතාවයයි. ඔබ වාර්තාවක් ඇතුළත් කර නොමැති වගුවක් සඳහා වත්මන් IDENTITY අගය ලබා ගැනීමට අවශ්‍ය නම් ඔබට මෙය භාවිතා කළ හැකිය.


2
මේ සඳහා ඔබ කිසි විටෙකත් @@ අනන්‍යතාවය භාවිතා නොකළ යුතුය. යමෙක් පසුව ප්‍රේරකයක් එකතු කළහොත් ඔබට දත්ත අඛණ්ඩතාව නැති වේ. @@ අනන්‍යතාවය අතිශයින්ම භයානක පුරුද්දකි.
HLGEM

1
"ඔබ <<not>> වාර්තාවක් ඇතුළත් කළ වගුවක වටිනාකම." ඇත්තටම?
අබ්දුල් සබූර්

13

මට SQL සේවාදායකයේ වෙනත් සංස්කරණ සමඟ කතා කළ නොහැක, නමුත් 2012 දී ප්‍රතිදානය කිරීම කෙලින්ම ක්‍රියා කරයි. ඔබට තාවකාලික මේසයක් සමඟ කරදර වීමට අවශ්‍ය නැත.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)

මාර්ගය වන විට, පේළි කිහිපයක් ඇතුළත් කිරීමේදී මෙම තාක්ෂණය ද ක්රියා කරයි.

INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
    (...),
    (...),
    (...)

ප්‍රතිදානය

ID
2
3
4

ඔබට පසුව එය භාවිතා කිරීමට අවශ්‍ය නම්, ඔබට තාවකාලික වගුව අවශ්‍ය යැයි මම සිතමි
JohnOsborne

@ ජෝන් ඔස්බෝන් ඔබ කැමති නම් තාවකාලික වගුවක් භාවිතා කිරීමට ඔබව සාදරයෙන් පිළිගනිමු, නමුත් මගේ අදහස වූයේ එය අවශ්‍යතාවයක් නොවන OUTPUTබවයි. ඔබට තාවකාලික වගුව අවශ්‍ය නොවේ නම්, ඔබේ විමසුම අවසන් වන්නේ වඩාත් සරල ය.
MarredCheese

10

සෑම විටම විෂය පථය () ​​භාවිතා කරන්න, වෙනත් කිසිවක් අවශ්‍ය නොවේ.


13
හරියටම කිව නොහැකි කවදාවත් නමුත් 99 වතාවක් 100 න්, ඔබ Scope_Identity () භාවිතා කරන්නේ.
සී.ජේ.එම්

ඔබ වෙනත් කිසිවක් භාවිතා කර ඇත්තේ කුමක් සඳහාද?
erikkallen

11
ඔබ INSERT-SELECT සමඟ පේළි කිහිපයක් ඇතුල් කරන්නේ නම්, ඔබට OUTPUT වගන්තිය
KM

1
@KM: ඔව්, නමුත් මම යොමු කළේ විෂය පථය_ හඳුනාගැනීම එදිරිව @@ අනන්‍යතාවය එදිරිව හැඳුනුම්_ කාලීන. OUTPUT යනු සම්පූර්ණයෙන්ම වෙනස් පන්තියක් වන අතර බොහෝ විට ප්‍රයෝජනවත් වේ.
erikkallen

2
මෙම ප්‍රශ්නයට ඔරීගේ ( stackoverflow.com/a/6073578/2440976 ) පිළිතුර බලන්න - සමාන්තරව, සහ හොඳම භාවිතයක් ලෙස, ඔබ ඔහුගේ සැකසුම අනුගමනය කිරීම නුවණට හුරුය ... ඉතා දීප්තිමත්!
ඩෑන් බී

2

ඔබ ඇතුළු කරන පේළි වල අනන්‍යතාවය සහතික කිරීමට තවත් ක්‍රමයක් නම් අනන්‍යතා අගයන් නියම කර SET IDENTITY_INSERT ONපසුව භාවිතා කිරීමයි OFF. අනන්‍යතා අගයන් යනු කුමක්දැයි ඔබ හරියටම දන්නා බව මෙය සහතික කරයි! අගයන් භාවිතයේ නොමැති තාක් කල් ඔබට මෙම අගයන් අනන්‍යතා තීරුවට ඇතුළු කළ හැකිය.

CREATE TABLE #foo 
  ( 
     fooid   INT IDENTITY NOT NULL, 
     fooname VARCHAR(20) 
  ) 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

SET IDENTITY_INSERT #foo ON 

INSERT INTO #foo 
            (fooid, 
             fooname) 
VALUES      (1, 
             'one'), 
            (2, 
             'Two') 

SET IDENTITY_INSERT #foo OFF 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

INSERT INTO #foo 
            (fooname) 
VALUES      ('Three') 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

-- YOU CAN INSERT  
SET IDENTITY_INSERT #foo ON 

INSERT INTO #foo 
            (fooid, 
             fooname) 
VALUES      (10, 
             'Ten'), 
            (11, 
             'Eleven') 

SET IDENTITY_INSERT #foo OFF 

SELECT @@Identity            AS [@@Identity], 
       Scope_identity()      AS [SCOPE_IDENTITY()], 
       Ident_current('#Foo') AS [IDENT_CURRENT] 

SELECT * 
FROM   #foo 

ඔබ වෙනත් ප්‍රභවයකින් දත්ත පූරණය කරන්නේ නම් හෝ දත්ත සමුදායන් දෙකකින් දත්ත ඒකාබද්ධ කරන්නේ නම් මෙය ඉතා ප්‍රයෝජනවත් තාක්‍ෂණයකි.


2

A එකක් සාදා uuidඑය තීරුවකට ඇතුළු කරන්න. එවිට ඔබට පහසුවෙන් ඔබේ පේළිය uuid සමඟ හඳුනාගත හැකිය. ඔබට ක්‍රියාත්මක කළ හැකි එකම 100% වැඩ කරන විසඳුම එයයි. අනෙක් සියලුම විසඳුම් ඉතා සංකීර්ණ හෝ එකම අවස්ථා වලදී ක්‍රියා නොකරයි. උදා:

1) පේළිය සාදන්න

INSERT INTO table (uuid, name, street, zip) 
        VALUES ('2f802845-447b-4caa-8783-2086a0a8d437', 'Peter', 'Mainstreet 7', '88888');

2) සාදන ලද පේළිය ලබා ගන්න

SELECT * FROM table WHERE uuid='2f802845-447b-4caa-8783-2086a0a8d437';

uuidදත්ත සමුදායේ දර්ශකයක් නිර්මාණය කිරීමට අමතක නොකරන්න . එබැවින් පේළිය වේගයෙන් සොයාගත හැකිය.
ෆ්‍රෑන්ක් රෝත්

Node.js සඳහා ඔබට මෙම මොඩියුලය භාවිතා කර සරලවම uuid නිර්මාණය කළ හැකිය : https://www.npmjs.com/package/uuid. const uuidv4 = require('uuid/v4'); const uuid = uuidv4()
ෆ්‍රෑන්ක් රෝත්

2
GUID යනු අනන්‍යතා අගයක් නොවේ, සරල නිඛිලයකට සාපේක්ෂව එයට පසුපෙළ කිහිපයක් ඇත.
ඇලෙජැන්ඩ්‍රෝ

UNIQUEIDENTIFIERපෙරනිමියෙන් දත්ත සමුදායක් ලෙස SQL වගු මට්ටමින් UUID ජනනය කරන්නේ newid()නම් ඔබට මෙම ක්‍රමය භාවිතා කර එය ලබා ගත නොහැක. එබැවින් ඔබට ඇතුල් කිරීමට අවශ්‍ය වනු ඇත, UUID හිස්ව තබා එය ලබා ගැනීම සඳහා OUTPUT INSERTED.uuid කරන්න
කීත් ඊ. ට

1

මෙය පැරණි නූලක් වුවද, මෙය කිරීමට නව ක්‍රමයක් ඇත, එමඟින් සේවාදායකය නැවත පණගැන්වීමෙන් පසු අනන්‍යතා අගයන්හි ඇති හිඩැස් වැනි SQL සේවාදායකයේ පැරණි අනුවාදවල IDENTITY තීරුවේ ඇති සමහර අන්තරායන් මඟහරවා ගත හැකිය . අනුපිළිවෙල SQL Server 2016 හි ලබා ගත හැකි අතර ඉදිරියට යන නවතම ක්‍රමය වන්නේ TSQL භාවිතා කරමින් අනුක්‍රමික වස්තුවක් නිර්මාණය කිරීමයි. මෙය SQL සේවාදායකයේ ඔබේම සංඛ්‍යා අනුක්‍රමික වස්තුවක් නිර්මාණය කිරීමට සහ එය වැඩි වන ආකාරය පාලනය කිරීමට ඔබට ඉඩ සලසයි.

මෙන්න උදාහරණයක්:

CREATE SEQUENCE CountBy1  
    START WITH 1  
    INCREMENT BY 1 ;  
GO  

ඊළඟ අනුක්‍රමික හැඳුනුම්පත ලබා ගැනීම සඳහා TSQL හි ඔබ පහත සඳහන් දෑ කරනු ඇත:

SELECT NEXT VALUE FOR CountBy1 AS SequenceID
GO

CREATE SEQUENCE සහ NEXT VALUE FOR සඳහා සබැඳි මෙන්න


අනුක්‍රමයන්ට හිඩැස් වැනි අනන්‍යතාවයේ ගැටලු ඇත (ඒවා ඇත්ත වශයෙන්ම ගැටළු නොවේ).
ඇලෙජැන්ඩ්‍රෝ

SQL සේවාදායකය නැවත ආරම්භ කරන විට අනන්‍යතා හිඩැස් අහඹු ලෙස සිදුවිය. සංවර්ධකයා විසින් ජනනය කරන ලද අනුක්‍රමය භාවිතා නොකරන්නේ නම් හෝ ඊළඟ අනුක්‍රමික හැඳුනුම්පත භාවිතා කිරීමට තිබූ ගනුදෙනුවක් පෙරළා දැමුවහොත් මිස, නව අනුක්‍රමික වර්ධකවල මෙම හිඩැස් ඇති නොවේ. සබැඳි ප්‍රලේඛනයෙන්: අනුක්‍රමික වස්තුව එහි අර්ථ දැක්වීම අනුව සංඛ්‍යා උත්පාදනය කරයි, නමුත් අනුක්‍රමික වස්තුව සංඛ්‍යා භාවිතා කරන ආකාරය පාලනය නොකරයි. ගනුදෙනුවක් ආපසු පෙරළෙන විට, ... හෝ වගු වල භාවිතා නොකර අනුක්‍රමික අංක වෙන් කළ විට, අනුක්‍රමික අංක වගුවකට ඇතුළත් කළ හැකිය.
ස්ටීවන් ජේ

-1

ඔබගේ ඇතුළත් කිරීමේ ප්‍රකාශයෙන් පසුව ඔබට මෙය එකතු කළ යුතුය. දත්ත ඇතුළු කරන වගුවේ නම ගැන වග බලා ගන්න.ඔබගේ ඇතුල් කිරීමේ ප්‍රකාශය මඟින් ඔබට පේළිය බලපාන්නේ නැති තැනට වත්මන් පේළිය ලැබෙනු ඇත.

IDENT_CURRENT('tableName')

2
මෙම යෝජනාවට මීට පෙර කිහිප වතාවක්ම පිළිතුරු ලබා දී ඇති බව ඔබ දුටුවාද?
ටී.

ඔව්. නමුත් මම උත්සාහ කරන්නේ විසඳුම මගේම ආකාරයෙන් විස්තර කිරීමටයි.
ඛාන් අටූර් රහ්මාන්

1
ඔබගේ ඇතුළු කිරීමේ ප්‍රකාශය සහ ඔබගේ IDENT_CURRENT () ඇමතුම අතර වෙනත් අයෙකු පේළියක් ඇතුල් කර ඇත්නම්, වෙනත් අයෙකු ඇතුළු කර ඇති වාර්තාවේ හැඳුනුම්පත ඔබට ලැබෙනු ඇත - බොහෝ විට ඔබට අවශ්‍ය දේ නොවේ. ඉහත බොහෝ පිළිතුරු වල සඳහන් කර ඇති පරිදි - බොහෝ අවස්ථාවලදී ඔබ භාවිතා කළ යුත්තේ SCOPE_IDENTITY () ය.
ට්‍රොන්ඩ්ස්ටර්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.