सम्मिलित पंक्ति की पहचान प्राप्त करने का सर्वोत्तम तरीका?


1118

IDENTITYसम्मिलित पंक्ति प्राप्त करने का सबसे अच्छा तरीका क्या है ?

मैं के बारे में पता @@IDENTITYहै और IDENT_CURRENTऔर SCOPE_IDENTITYलेकिन प्रत्येक से जुड़ी पक्ष-विपक्ष को नहीं समझते।

क्या कोई कृपया मतभेदों की व्याख्या कर सकता है और जब मुझे प्रत्येक का उपयोग करना चाहिए?


5
INSERT INTO Table1(fields...) OUTPUT INSERTED.id VALUES (...), या पुरानी विधि: INSERT INTO Table1(fields...) VALUES (...); SELECT SCOPE_IDENTITY();आप इसे ExecuteScalar () का उपयोग करके c # में प्राप्त कर सकते हैं।
S.Serpooshan

4
अन्य उत्तरों की तुलना में यह कैसे बेहतर है? (यह भी - आप इसे टिप्पणी के बजाय उत्तर के रूप में क्यों नहीं पोस्ट कर रहे हैं) कृपया एक पूर्ण उत्तर लिखें (और बताएं कि यह पोस्ट किए गए लोगों की तुलना में बेहतर विकल्प क्यों है - यदि संस्करण विशिष्ट है, तो ऐसा कहें)।
ओड

यह एक संक्षिप्त सारांश के समान है। ; डी स्वीकार किए गए जवाब में OUTPUT क्लॉज सिंटैक्स का उल्लेख नहीं है और एक नमूना का अभाव है। अन्य पदों में भी नमूने इतने साफ नहीं हैं ...
S.Serpooshan

2
@saeedserpooshan - फिर उसे संपादित करें। आप ऐसा कर सकते हैं, आप जानते हैं? देखें कि वह उत्तर कब पोस्ट किया गया था? OUTPUTSQL सर्वर में क्लॉज़ को पूर्ववर्ती करता है ।
ओड

जवाबों:


1433
  • @@IDENTITYसभी स्कोपों ​​में, वर्तमान सत्र में किसी भी तालिका के लिए उत्पन्न अंतिम पहचान मूल्य देता है। आपको यहां सावधान रहने की जरूरत है , क्योंकि यह स्कोप के पार है। आप अपने वर्तमान विवरण के बजाय, ट्रिगर से मूल्य प्राप्त कर सकते हैं।

  • SCOPE_IDENTITY()मौजूदा सत्र और मौजूदा दायरे में किसी भी तालिका के लिए उत्पन्न अंतिम पहचान मूल्य देता है। आम तौर पर आप क्या उपयोग करना चाहते हैं

  • IDENT_CURRENT('tableName')किसी भी सत्र और किसी भी क्षेत्र में एक विशिष्ट तालिका के लिए उत्पन्न अंतिम पहचान मूल्य देता है। यह आपको यह निर्दिष्ट करने देता है कि आप किस तालिका से मान चाहते हैं, यदि उपरोक्त दो काफी नहीं हैं जो आपको चाहिए ( बहुत दुर्लभ )। जैसा कि @ गाइ स्टारबक ने उल्लेख किया है, "यदि आप एक तालिका के लिए वर्तमान पहचान मूल्य प्राप्त करना चाहते हैं, तो आप इसका उपयोग कर सकते हैं, जिसमें आपने रिकॉर्ड नहीं डाला है।"

  • OUTPUTखंड के INSERTबयान आप हर पंक्ति है कि उस बयान के माध्यम से डाला गया था का उपयोग करने देगा। चूँकि यह विशिष्ट कथन से अलग है, इसलिए यह ऊपर दिए गए अन्य कार्यों की तुलना में अधिक सीधा है। हालाँकि, यह थोड़ी अधिक क्रिया है (आपको तालिका चर / अस्थायी तालिका में सम्मिलित करने की आवश्यकता होगी और फिर उस प्रश्न को छोड़ना होगा) और यह एक त्रुटि परिदृश्य में भी परिणाम देता है जहाँ कथन को वापस लाया गया है। कहा कि, यदि आपकी क्वेरी समानांतर निष्पादन योजना का उपयोग करती है, तो पहचान प्राप्त करने के लिए यह एकमात्र गारंटीकृत तरीका है (समानता को बंद करने की कमी)। हालाँकि, इसे ट्रिगर करने से पहले निष्पादित किया जाता है और इसका उपयोग ट्रिगर-जेनरेट किए गए मानों को वापस करने के लिए नहीं किया जा सकता है।


48
SCOPE_IDENTITY के साथ ज्ञात बग () गलत मान लौटाता है : blog.sqlauthority.com/2009/03/24/… । चारों ओर का काम INSERT को मल्टी प्रोसेसर समानांतर योजना में नहीं चलाना है या OUTPUT क्लॉज
KM का

3
लगभग हर बार जब मैं कभी भी 'पहचान' चाहता हूं, तो मैंने रिकॉर्ड की कुंजी (ओं) को जानना चाहा है। यदि आपकी स्थिति ऐसी है, तो आप OUTPUT क्लॉज का उपयोग करना चाहते हैं। यदि आप कुछ और चाहते हैं, तो bdukes प्रतिक्रिया को पढ़ने और समझने के प्रयास को लागू करें।
जेरी

3
साथ outputआप की दुकान करने के लिए एक अस्थायी तालिका बनाने और परिणाम क्वेरी करने के लिए जरूरत नहीं है। बस intoआउटपुट क्लॉज के हिस्से को छोड़ दें और यह उन्हें एक परिणाम पर आउटपुट करेगा।
sp

96
दूसरों को पैनिंग से बचाने के लिए, ऊपर उल्लिखित बग SQL Server 2008 R2 सर्विस पैक 1 के लिए संचयी अद्यतन 5 में तय किया गया था
GaTechThomas

1
@niico, मुझे लगता है कि सिफारिश वही है जो वह रही है, जो कि OUTPUT"सबसे अच्छा" है, जब तक आप ट्रिगर का उपयोग नहीं कर रहे हैं और त्रुटियों को संभाल रहे हैं, लेकिन SCOPE_IDENTITYसबसे सरल और बहुत कम ही समस्याएं हैं
bdukes

180

मेरा मानना ​​है कि सम्मिलित आईडी प्राप्त करने का सबसे सुरक्षित और सबसे सटीक तरीका आउटपुट क्लॉज का उपयोग होगा।

उदाहरण के लिए (निम्नलिखित 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 को छोड़ दिया है तो सुनिश्चित नहीं हैं कि अगर OUTPUT उपलब्ध था तो)
HLGEM

1
@HLGEM SQL Server 2005 के लिएOUTPUT एक MSDN पृष्ठ है , इसलिए ऐसा लगता है कि यह सिर्फ SQL Server 2000 है और इससे पहले जो इसके बिना हैं
bdukes

6
वू हू! OUTPUT CLAUSE चट्टानें :) जो मेरे वर्तमान कार्य को सरल बनाएगी। पहले उस कथन को नहीं जानते थे। आप लोगों को धन्यवाद!
स्विसकोडर

8
वास्तव में संक्षिप्त उदाहरण के लिए केवल डाली गई आईडी प्राप्त करें, एक नज़र डालें: stackoverflow.com/a/10999467/2003325
ल्यूक

OUTPUT के साथ INTO का आपका उपयोग एक अच्छा विचार है। देखें: blogs.msdn.microsoft.com/sqlprogrammability/2008/07/11/… (यहां एक टिप्पणी से: stackoverflow.com/questions/7917695/… )
shlgug

112

मैं अन्य लोगों के समान बात कह रहा हूं, इसलिए सभी लोग सही हैं, मैं इसे और अधिक स्पष्ट करने की कोशिश कर रहा हूं।

@@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

@MartinSmith क्लाइंट इस समस्या को हल करने के लिए अपने सर्वर क्लस्टर पर डाउनटाइम की अनुमति देने के लिए तैयार नहीं था (यह मजाक नहीं है), इसलिए हमारे लिए सभी एसक्यूएल को फिर से लिखने के outputबजाय एकमात्र समाधान था scope_identity()। मैंने उत्तर में क्लस्टरिंग के बारे में FUD को हटा दिया है।
इयान केम्प

1
धन्यवाद, यह एकमात्र उदाहरण है जिसे मैंने पाया है कि यह दिखाता है कि केवल आउटपुट के बजाय एक चर में आउटपुट से मूल्य का उपयोग कैसे किया जाए।
सीन रे

26

जोड़ना

SELECT CAST(scope_identity() AS int);

आपके सम्मिलित एसक्यूएल बयान के अंत में, फिर

NewId = command.ExecuteScalar()

इसे पुनः प्राप्त करेंगे।


18

जब आप एंटिटी फ्रेमवर्क का उपयोग करते हैं, तो यह 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

आउटपुट परिणाम एक अस्थायी तालिका चर में संग्रहीत किए जाते हैं, तालिका में वापस शामिल हो जाते हैं, और तालिका के बाहर पंक्ति मान लौटाते हैं।

नोट: मुझे नहीं पता कि ईएफ आंतरिक तालिका में वास्तविक तालिका में वापस क्यों शामिल होगा (किन परिस्थितियों में दो मैच होंगे)।

लेकिन यही ईएफ करता है।

यह तकनीक ( OUTPUT) केवल SQL Server 2008 या नए पर उपलब्ध है।

संपादित करें - शामिल होने का कारण

एंटिटी फ्रेमवर्क मूल तालिका में शामिल होने के बजाय केवल OUTPUTमूल्यों का उपयोग करने के कारण वापस आ जाता है क्योंकि ईएफ इस तकनीक का उपयोग rowversionनई सम्मिलित पंक्ति को प्राप्त करने के लिए भी करता है ।

आप विशेषता का उपयोग करकेTimestamp अपने इकाई ढांचे के मॉडल में आशावादी संगामिति का उपयोग कर सकते हैं : conc

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ट्रिगर के साथ एक मेज पर प्रदर्शन करते समय , आप एक खंड का उपयोग नहीं कर सकतेOUTPUTUPDATEएक के साथ प्रयास करना 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 कॉलम में सम्मिलित अंतिम मान लौटाते हैं।

@@ पहचान और SCOPE_IDENTITY मौजूदा सत्र में किसी भी तालिका में उत्पन्न अंतिम पहचान मूल्य लौटाएगी। हालाँकि, SCOPE_IDENTITY केवल मौजूदा दायरे के भीतर मान लौटाता है; @@ पहचान एक विशिष्ट दायरे तक सीमित नहीं है।

IDENT_CURRENT गुंजाइश और सत्र तक सीमित नहीं है; यह एक निर्दिष्ट तालिका तक सीमित है। IDENT_CURRENT किसी भी सत्र और किसी भी क्षेत्र में एक विशिष्ट तालिका के लिए उत्पन्न पहचान मान लौटाता है। अधिक जानकारी के लिए, IDENT_CURRENT देखें।

  • IDENT_CURRENT एक फ़ंक्शन है जो एक तर्क के रूप में एक तालिका लेता है।
  • जब आप टेबल पर ट्रिगर करते हैं तो @@ पहचान परिणाम भ्रामक हो सकता है
  • SCOPE_IDENTITY आपके नायक का सबसे अधिक समय है।

14

@@ पहचान वर्तमान एसक्यूएल कनेक्शन का उपयोग करके सम्मिलित अंतिम पहचान है। एक सम्मिलित संग्रहीत कार्यविधि से लौटने के लिए यह एक अच्छा मूल्य है, जहाँ आपको बस अपने नए रिकॉर्ड के लिए सम्मिलित पहचान की आवश्यकता होती है, और अगर बाद में अधिक पंक्तियों को जोड़ा गया तो परवाह न करें।

SCOPE_IDENTITY वर्तमान SQL कनेक्शन का उपयोग करके डाली गई अंतिम पहचान है, और वर्तमान दायरे में - अर्थात, यदि आपके सम्मिलित किए जाने के बाद एक ट्रिगर के आधार पर दूसरी IDENTITY सम्मिलित की गई थी, तो यह SCOPE_IDENTITY में परिलक्षित नहीं होगी, केवल आपके द्वारा किया गया इन्सर्ट । सच कहूं, तो मुझे कभी भी इसका उपयोग करने का कारण नहीं मिला।

IDENT_CURRENT (tablename) कनेक्शन या कार्यक्षेत्र की परवाह किए बिना डाली गई अंतिम पहचान है। यदि आप एक तालिका के लिए वर्तमान पहचान मूल्य प्राप्त करना चाहते हैं, तो आप इसका उपयोग कर सकते हैं, जिसमें आपने रिकॉर्ड नहीं डाला है।


2
आपको इस उद्देश्य के लिए कभी भी @@ पहचान का उपयोग नहीं करना चाहिए। यदि कोई बाद में ट्रिगर जोड़ता है, तो आप डेटा अखंडता खो देंगे। @@ पहचानिया एक बेहद खतरनाक प्रथा है।
HLGEM

1
"आपके पास एक तालिका के लिए मान << नहीं >> में एक रिकॉर्ड डाला।" वास्तव में?
अब्दुल सबूर

13

मैं SQL सर्वर के अन्य संस्करणों से बात नहीं कर सकता, लेकिन 2012 में, आउटपुट सीधे सीधे ठीक काम करता है। आपको एक अस्थायी तालिका से परेशान होने की आवश्यकता नहीं है।

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

वैसे, यह तकनीक कई पंक्तियों को सम्मिलित करते समय भी काम करती है।

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

उत्पादन

ID
2
3
4

यदि आप इसे बाद में उपयोग करना चाहते हैं, तो मुझे लगता है कि आपको अस्थायी तालिका की आवश्यकता है
JohnOsborne

@ जॉनसनबॉर्न यदि आप चाहें तो एक अस्थायी तालिका का उपयोग करने के लिए आपका स्वागत है, लेकिन मेरा कहना यह था कि इसकी आवश्यकता नहीं है OUTPUT। यदि आपको अस्थायी तालिका की आवश्यकता नहीं है, तो आपकी क्वेरी बहुत सरल हो जाती है।
मैरेडेचेस

10

हमेशा गुंजाइश गुंजाइश () का उपयोग करें, वहाँ कुछ और के लिए एक की जरूरत नहीं है।


13
नहीं काफी कभी नहीं लेकिन 100 में से 99 बार, तो आप SCOPE_IDENTITY इस्तेमाल करेंगे ()।
CJM

आपने अभी तक किसी और चीज का क्या उपयोग किया है?
erkkallen

11
यदि आप INSERT-SELECT के साथ कई पंक्तियाँ सम्मिलित करते हैं, तो आपको OUTPUT क्लैट
KM

1
@ केएम: हाँ, लेकिन मैंने गुंजाइश_ पहचान बनाम @@ पहचान बनाम समकालिकता का उल्लेख किया है। OUTPUT एक पूरी तरह से अलग वर्ग है और अक्सर उपयोगी होता है।
एरिक्कलेन

2
इस सवाल का जवाब Orry's ( stackoverflow.com/a/6073578/2440976 ) देखें - समानतावाद में, और सिर्फ एक सर्वोत्तम अभ्यास के रूप में, आप समझदारी से उसके सेटअप का पालन करेंगे ... बस शानदार!
दान बी

2

एक बनाएं uuidऔर इसे एक कॉलम में डालें। फिर आप अपनी पंक्ति को आसानी से uuid से पहचान सकते हैं। आप लागू कर सकते हैं केवल 100% काम कर रहे समाधान Thats अन्य सभी समाधान बहुत जटिल हैं या एक ही किनारे के मामलों में काम नहीं कर रहे हैं। उदाहरण के लिए:

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/uuidconst uuidv4 = require('uuid/v4'); const uuid = uuidv4()
फ्रैंक रोथ 12

एक GUID एक पहचान मूल्य नहीं है, यह एक साधारण पूर्णांक की तुलना में कुछ पीछे हटता है।
अलेजांद्रो

1

आपके द्वारा सम्मिलित पंक्तियों की पहचान की गारंटी देने का एक अन्य तरीका पहचान मूल्यों को निर्दिष्ट करना 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 

यदि आप किसी अन्य स्रोत से डेटा लोड कर रहे हैं या दो डेटाबेस आदि से डेटा मर्ज कर रहे हैं तो यह बहुत उपयोगी तकनीक हो सकती है।


0

भले ही यह एक पुराना धागा है, लेकिन ऐसा करने का एक नया तरीका है जो SQL सर्वर के पुराने संस्करणों में IDENTITY स्तंभ के कुछ नुकसान से बचा जाता है, जैसे सर्वर रिबूट के बाद पहचान मूल्यों में अंतराल । एसक्यूएल सर्वर 2016 में अनुक्रम उपलब्ध हैं और फॉरवर्ड जो कि TSQL का उपयोग करके एक SEQUENCE ऑब्जेक्ट बनाना है। यह आपको SQL सर्वर में अपनी स्वयं की संख्यात्मक अनुक्रम ऑब्जेक्ट बनाने और यह कैसे बढ़ाता है इसे नियंत्रित करने की अनुमति देता है।

यहाँ एक उदाहरण है:

CREATE SEQUENCE CountBy1  
    START WITH 1  
    INCREMENT BY 1 ;  
GO  

फिर TSQL में आप अगले अनुक्रम आईडी प्राप्त करने के लिए निम्न कार्य करेंगे:

SELECT NEXT VALUE FOR CountBy1 AS SequenceID
GO

यहाँ लिंक बनाने के लिए लिंक और अगले मूल्य के लिए कर रहे हैं


दृश्यों की पहचान की बहुत ही समस्याएं हैं, जैसे अंतराल (जो वास्तव में समस्याएं नहीं हैं)।
अलेजांद्रो

-1

आपके इंसर्ट स्टेटमेंट के बाद आपको इसे जोड़ना होगा। और उस तालिका के नाम के बारे में सुनिश्चित करें जहां डेटा सम्मिलित हो रहा है। आपको वर्तमान पंक्ति नहीं मिलेगी जहां पंक्ति आपके सम्मिलित विवरण से प्रभावित होती है।

IDENT_CURRENT('tableName')

2
क्या आपने देखा कि यह सटीक सुझाव पहले भी कई बार उत्तर दिया जा चुका है।
टीटी।

हाँ। लेकिन मैं अपने तरीके से समाधान का वर्णन करने की कोशिश कर रहा हूं।
खान अताउर रहमान

और अगर आपके इंसर्ट स्टेटमेंट और आपके IDENT_CURRENT () कॉल के बीच में किसी और ने एक पंक्ति डाली है, तो आपको उस रिकॉर्ड की आईडी मिल जाएगी जिसे किसी और ने डाला है - शायद वह नहीं जो आप चाहते हैं। जैसा कि ऊपर दिए गए अधिकांश उत्तरों में कहा गया है - ज्यादातर मामलों में आपको SCOPE_IDENTITY () का उपयोग करना चाहिए।
Trondster
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.