Scope_Identity (), Identity (), @@ Identity, और Ident_Current () के बीच क्या अंतर है?


191

मैं जानता हूँ कि Scope_Identity(), Identity(), @@Identity, और Ident_Current()सभी पहचान स्तंभ के मूल्य मिलता है, लेकिन मैं अंतर पता करना अच्छा लगेगा।

मेरे द्वारा किए गए विवाद का एक हिस्सा यह है कि वे इन कार्यों के लिए लागू किए गए दायरे से क्या मतलब है?

मैं उन्हें इस्तेमाल करने के विभिन्न परिदृश्यों का एक सरल उदाहरण भी पसंद करूंगा?


2
SCOPE_IDENTITY और @@ पहचान के लिए SQL सर्वर में मौजूद समानांतर निष्पादन बग के बारे में मत भूलना: support.microsoft.com/default.aspx?scid=kb-en-US-2019779
David d C Freitas

@DaviddCeFreitas - मैं बग के बारे में पढ़ने के लिए उत्सुक हूं, लेकिन लिंक टूटा हुआ प्रतीत होता है (या कम से कम, यह एएसपी त्रुटि फेंक रहा है)।
rory.ap

2
वास्तव में, मैंने इसे पाया: support.microsoft.com/en-us/kb/2019779
rory.ap

फिक्स को उस पुराने KB लेख
जॉर्ज बीरबिलिस

जवाबों:


394
  • @@identityसमारोह एक ही सत्र में किया गया अंतिम पहचान देता है।
  • scope_identity()समारोह एक ही सत्र और एक ही दायरे में किया गया अंतिम पहचान देता है।
  • ident_current(name)एक विशिष्ट तालिका या किसी सत्र में देखने के लिए किया गया अंतिम पहचान देता है।
  • identity()समारोह, एक पहचान पाने के लिए नहीं किया जाता है यह एक में एक पहचान बनाने के लिए प्रयोग किया जाता है select...intoक्वेरी।

सत्र डेटाबेस कनेक्शन है। गुंजाइश वर्तमान क्वेरी या वर्तमान संग्रहीत कार्यविधि है।

ऐसी स्थिति जहां कार्य scope_identity()और @@identityकार्य भिन्न होते हैं, यदि आपके पास टेबल पर एक ट्रिगर है। यदि आपके पास एक क्वेरी है जो एक रिकॉर्ड सम्मिलित करती है, जिससे ट्रिगर कहीं और रिकॉर्ड दर्ज कर सकता है, तो scope_identity()फ़ंक्शन क्वेरी द्वारा बनाई गई पहचान लौटा देगा, जबकि @@identityफ़ंक्शन ट्रिगर द्वारा बनाई गई पहचान को वापस कर देगा।

इसलिए, आम तौर पर आप scope_identity()फ़ंक्शन का उपयोग करेंगे ।


14
मैंने इसे उत्तर के रूप में चुना, क्योंकि "एक स्थिति जहां गुंजाइश_ घटना () और @@ पहचान ..." पैराग्राफ। इसने चीजों को और अधिक स्पष्ट किया।
तेबो

1
जैसा कि डेविड फ्रीटस ने ऊपर उल्लेख किया है, स्कोप_सिटी के कार्यान्वयन में एक बग है, इसलिए मैं एक वैकल्पिक विधि का उपयोग करने की सलाह देता हूं, ऑउटपूट क्लॉज। नीचे मेरा जवाब देखें।
सेबस्टियन मेन

@Guffa - "सत्र डेटाबेस कनेक्शन है"। यदि आप कनेक्शन पूलिंग का उपयोग कर रहे हैं तो क्या कनेक्शन पूरे सत्र में बनाए रखा गया है?
डेव ब्लैक

1
यह एक रोल मॉडल उत्तर है। विशेष रूप से, SQL और SQL सर्वर के साथ काम करना अजीब हो सकता है, और यह चीजों को बहुत स्पष्ट, आम आदमी के तरीके से समझाता है, जबकि अभी भी काफी जानकारीपूर्ण है। ऐसा लगता है जैसे दो डेटाबेस विशेषज्ञों के बीच संचार किया जा रहा है, जो अन्य एसई जवाब का एक बहुत कुछ है।
पैन्ज़रक्रिस

@DaveBlack मैं क्या पढ़ता हूं: नहीं, सत्र पूल में बनाए नहीं रखा गया है, सत्र कनेक्ट () के बाद आपकी स्क्रिप्ट-रन के लिए अद्वितीय है। जब पूलिंग ... SQL सर्वर के लिए PHP ODBC कनेक्शन पूलिंग का उपयोग करता है। जब पूल से कनेक्शन का उपयोग किया जाता है, तो कनेक्शन स्थिति रीसेट हो जाती है। कनेक्शन बंद करने से पूल में कनेक्शन वापस आ जाता है। (नोट: linux / mac के लिए टिप्पणी देखें) docs.microsoft.com/en-us/sql/connect/php/…
GDmac

42

अच्छा प्रश्न।

  • @@IDENTITY: आपके SQL कनेक्शन (SPID) पर उत्पन्न अंतिम पहचान मान लौटाता है। ज्यादातर समय यह वही होगा जो आप चाहते हैं, लेकिन कभी-कभी ऐसा नहीं होता है (जैसे कि जब ट्रिगर को ए के जवाब में निकाल दिया जाता है INSERT, और ट्रिगर किसी अन्य INSERTविवरण को निष्पादित करता है )।

  • SCOPE_IDENTITY(): वर्तमान क्षेत्र (यानी संग्रहीत कार्यविधि, ट्रिगर, फ़ंक्शन, आदि) में उत्पन्न अंतिम पहचान मान लौटाता है।

  • IDENT_CURRENT(): किसी विशिष्ट तालिका के लिए अंतिम पहचान मान देता है। पहचान मूल्य प्राप्त करने के लिए इसका उपयोग न करें INSERT, यह दौड़ की स्थिति (यानी एक ही टेबल पर पंक्तियों को सम्मिलित करने वाले कई कनेक्शन) के अधीन है।

  • IDENTITY(): तालिका में एक कॉलम को पहचान स्तंभ के रूप में घोषित करते समय उपयोग किया जाता है।

अधिक जानकारी के लिए, देखें: http://msdn.microsoft.com/en-us/library/ms187342.aspx

संक्षेप में: यदि आप पंक्तियों डालने हैं, और आप पंक्ति के लिए पहचान स्तंभ के मूल्य में जानना चाहते हैं तो आप बस डाला, हमेशा उपयोग SCOPE_IDENTITY()


16

यदि आप गुंजाइश और सत्र के बीच अंतर को समझते हैं तो इन तरीकों को समझना बहुत आसान होगा।

एडम एंडरसन द्वारा एक बहुत अच्छा ब्लॉग पोस्ट इस अंतर का वर्णन करता है:

सत्र का मतलब है कि वर्तमान कनेक्शन जो कमांड को निष्पादित कर रहा है।

स्कोप का अर्थ है एक कमांड का तत्काल संदर्भ। प्रत्येक संग्रहीत कार्यविधि कॉल अपने स्वयं के दायरे में निष्पादित होती है, और नेस्टेड कॉल निष्पादन प्रक्रिया के दायरे में एक नेस्टेड दायरे में निष्पादित होती है। इसी तरह, किसी एप्लिकेशन या SSMS से निष्पादित SQL कमांड अपने दायरे में निष्पादित होता है, और यदि वह कमांड किसी भी ट्रिगर को फायर करता है, तो प्रत्येक ट्रिगर अपने स्वयं के नेस्टेड दायरे में निष्पादित होता है।

इस प्रकार तीन पहचान पुनर्प्राप्ति विधियों के बीच अंतर इस प्रकार हैं:

@@identityइस सत्र में उत्पन्न अंतिम पहचान मान लेकिन कोई गुंजाइश नहीं है।

scope_identity()इस सत्र और इस दायरे में उत्पन्न अंतिम पहचान मान लौटाता है ।

ident_current()किसी भी सत्र और किसी भी क्षेत्र में किसी विशेष तालिका के लिए उत्पन्न अंतिम पहचान मूल्य देता है ।


11

स्कोप का अर्थ उस कोड संदर्भ से है , जो INSERTकथन का प्रदर्शन करता है SCOPE_IDENTITY(), जैसा कि वैश्विक दायरे के विपरीत है @@IDENTITY

CREATE TABLE Foo(
  ID INT IDENTITY(1,1),
  Dummy VARCHAR(100)
)

CREATE TABLE FooLog(
  ID INT IDENTITY(2,2),
  LogText VARCHAR(100)
)
go
CREATE TRIGGER InsertFoo ON Foo AFTER INSERT AS
BEGIN
  INSERT INTO FooLog (LogText) VALUES ('inserted Foo')
  INSERT INTO FooLog (LogText) SELECT Dummy FROM inserted
END

INSERT INTO Foo (Dummy) VALUES ('x')
SELECT SCOPE_IDENTITY(), @@IDENTITY 

अलग-अलग परिणाम देता है।


9

@David Freitas द्वारा उल्लिखित बग के कारण और 2012 में पेश किए गए नए सीक्वेंस फीचर की असंगति के कारण मैं इन तीनों से दूर रहने की सलाह दूंगा। इसके बजाय, आप सम्मिलित पहचान मान प्राप्त करने के लिए OUTPUT क्लॉज़ का उपयोग कर सकते हैं। अन्य लाभ यह है कि यदि आपने एक से अधिक पंक्ति सम्मिलित की हैं, तो भी OUTPUT काम करता है।

विवरण और उदाहरण के लिए यहां देखें: आइडेंटिटी क्राइसिस


मुझे लगता है कि यह जवाब अधिक ध्यान देने योग्य है।
Cheeze

दुर्भाग्य से INSERT ... OUTPUT Inserted.xx INSERT ट्रिगर्स के साथ काम नहीं करता है (वही UPDATE के लिए जाता है ... OUTPUT Updated.xx और UPDATE ट्रिगर्स)। वे INSERT ... OUTPUT INTO का उपयोग करने का सुझाव देते हैं, लेकिन यह बहुत ही क्रियात्मक है और ग्राहकों से एक का उपयोग करने के बजाय (संग्रहीत procs में) समस्याग्रस्त है। INSERT ... क्लाइंट-साइड कॉल के साथ उपयोग किए जाने पर OUTPUT Inserted.xx सुंदर है (यदि आपको ट्रिगर करने की आवश्यकता नहीं है, तो सम्मिलित करने के लिए और नई पंक्ति के लिए स्वतः पूर्ण आईडी वापस पाने के लिए एक ExecuteScalar की आवश्यकता है)।
जॉर्ज बीरबिलिस

6

समस्या को स्पष्ट करने के लिए @@Identity:

उदाहरण के लिए, यदि आप एक तालिका सम्मिलित करते हैं और उस तालिका में आवेषण @@Identityकरते हुए ट्रिगर होते हैं, तो ट्रिगर में प्रविष्टि ( log_idया कुछ और) scope_identity()से आईडी लौटाएगा , जबकि मूल तालिका में सम्मिलित से आईडी वापस कर देगा।

इसलिए यदि आपके पास कोई ट्रिगर नहीं है, scope_identity()और @@identityसमान मान लौटाएगा। यदि आपके पास ट्रिगर हैं, तो आपको यह सोचने की ज़रूरत है कि आप क्या मूल्य चाहते हैं।


4

Scope Identity: जमा किए गए कार्यविधि के भीतर जोड़े गए अंतिम रिकॉर्ड की पहचान।

@@Identity: क्वेरी बैच के भीतर जोड़े गए अंतिम रिकॉर्ड की पहचान, या क्वेरी के परिणामस्वरूप उदाहरण के लिए एक प्रक्रिया जो एक सम्मिलित करता है, फिर एक ट्रिगर आग लगाता है जो फिर एक रिकॉर्ड सम्मिलित करता है ट्रिगर से सम्मिलित रिकॉर्ड की पहचान वापस कर देगा।

IdentCurrent: तालिका के लिए आवंटित अंतिम पहचान।


3

यहाँ पुस्तक से एक और अच्छी व्याख्या है :

SCOPE_IDENTITY और @@ IDENTITY के बीच अंतर के लिए, मान लीजिए कि आपके पास एक संग्रहीत कार्यविधि P1 है जिसमें तीन कथन हैं:
- एक INSERT जो एक नई पहचान मान उत्पन्न करता है
- एक संग्रहीत कार्यविधि P2 के लिए एक कॉल जिसमें एक INSERT कथन भी होता है जो एक नया उत्पन्न करता है पहचान मूल्य
- एक कथन जो फ़ंक्शन SCOPE_IDENTITY और @@ पहचान पर सवाल उठाता है SCOPE_IDENTITY फ़ंक्शन P1 (समान सत्र और कार्यक्षेत्र) द्वारा उत्पन्न मान लौटाएगा। @@ पहचान समारोह P2 द्वारा उत्पन्न मान लौटाएगा (समान सत्र गुंजाइश के बावजूद)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.