संग्रहीत कार्यविधि के माध्यम से TSQL अनुक्रम का अनुकरण करें


17

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

कॉलम MetaKey varchar (अधिकतम) और MeatValueLong bigInt के साथ एक तालिका MetaInfo को देखते हुए। यह उम्मीद है कि 'आंतरिक-आईडी-अंतिम' के मेटा के साथ पंक्ति में अंतिम उच्चतम मूल्य निर्दिष्ट होगा। मैंने निम्नलिखित संग्रहित प्रक्रिया बनाई:

CREATE PROCEDURE [dbo].[uspGetNextID]
(
  @inID bigInt 
)
AS
BEGIN
    SET NOCOUNT ON;

    BEGIN TRANSACTION

    UPDATE MetaInfo WITH (ROWLOCK) 
      SET MetaValueLong = CASE 
                            WHEN ISNULL(MetaValueLong,0) > @inID THEN MetaValueLong+1 
                            ELSE @inID+1
                          END 
    WHERE MetaKey = 'Internal-ID-Last'

    SELECT MetaValueLong 
    FROM MetaInfo
    WHERE MetaKey = 'Internal-ID-Last'

    COMMIT TRANSACTION 

END

मेरा सवाल बस यह है कि क्या यह संग्रहित प्रक्रिया उम्मीद के मुताबिक काम करती है (सभी कॉलर्स को एक अनूठा परिणाम सौंपा जाएगा)?


@all: FYI करें, एसओ पर इस क्यू द्वारा उत्पन्न
gbn

जवाबों:


8

मेरे पास एक नज़र है और एमएस खुद ताले के बिना एक समाधान पेश करता है

http://blogs.msdn.com/b/sqlcat/archive/2006/04/10/sql-server-sequence-number.aspx

यह एक सरल अपडेट है जिसमें कोई लॉक संकेत नहीं है, लेकिन वे कहते हैं कि यह लॉक / गतिरोध है।

इस बारे में एसओ पर ज्यादा कुछ नहीं।

मैं आपके ROWLOCK ( "एक कतार के रूप में तालिका" (SO) के अनुसार, लेकिन READPAST के बिना UPDLOCK) जोड़ना चाहूंगा। यह एक 2 प्रक्रिया पढ़ना शुरू होने पर अलगाव को बढ़ा देगा।

हालाँकि, आपकी सभी प्रक्रियाएँ एक ही पंक्ति को पढ़ना / लिखना चाहती हैं, इससे मुझे स्वयं अनुमान होता है। READPAST सुरक्षित कॉन्सेप्ट की अनुमति देता है लेकिन इस मामले में यह बेकार है।

ध्यान दें: आप 2 के चयन के बजाय OUTPUT क्लॉज का उपयोग कर सकते हैं फिर आपको लेनदेन की आवश्यकता नहीं है।

HTH ...


1
आपने मुझे इसमें हरा दिया। ध्यान दें कि SQL सर्वर 2011 में SEQUENCE कार्यक्षमता शामिल है ताकि आपके स्वयं के आविष्कार की आवश्यकता जल्द ही दूर हो जाए (समय से पहले नहीं)।
nvogel

@ ड्डपोर्टस: वास्तव में। और बेहतर चलता है: dba.stackexchange.com/q/1635/630
gbn

@dportas - SEQUENCE इनपुट आवश्यकता के लिए अनुमति दे सकता है? सुविधा के अपने त्वरित पढ़ने में मैंने वह कार्यक्षमता नहीं देखी।
होगन

1

बाद की बातें याद आ रही हैं

1. SET XACT_ABORT
2. Exception Handling (Try Catch)

हाँ, यह आपकी स्थिति को पूरा करना चाहिए। एक बार लेनदेन में ऐसी स्थितियां आने के बाद, यह अपने कई उदाहरण बनाता है और बाद में, सभी कॉलर्स को एक अनूठा परिणाम सौंपा जाएगा


यदि मैं चयन करने से पहले प्रतिबद्ध हूं तो क्या कोई संभावना नहीं है कि मैं एक अलग कॉल द्वारा सहेजे गए परिणाम का चयन करूंगा?
होगन

इसके बारे में निश्चित नहीं है। लेकिन लगता है जैसे आप सही हैं। मुझे जांच करने की ज़रूरत है। धन्यवाद। BTW +1 के लिए, अच्छा प्रश्न ...

0

अधिक स्केलेबल समाधान जिसके लिए क्रमांकन की आवश्यकता नहीं होती है:

CREATE PROCEDURE [dbo].[uspGetNextID]
(
  @inID BIGINT OUT
)
AS
      SET NOCOUNT ON
      SET IDENTITY_INSERT SequenceTable ON;
      INSERT INTO SequenceTable (id) VALUES (@inID);
      SET IDENTITY_INSERT SequenceTable OFF;
      INSERT INTO SequenceTable DEFAULT VALUES;
      DELETE FROM SequenceTable WITH (READPAST);
      SET @inID = SCOPE_IDENTITY();
RETURN;

ओपी को उपयोगकर्ताओं को एक मूल्य में पारित करने की अनुमति देने की आवश्यकता है जो इसे जटिल बनाता है ...
gbn

@ डीडीपास - साभार मुझे इस दृष्टिकोण के बारे में पता था, लेकिन इनपुट पैरामीटर के कारण यह यहां काम नहीं करता है।
होगन

@ होगन, मैंने इनपुट पैरामीटर को संभालने के लिए अपने सुझाव को संशोधित किया है। हालांकि यह ज्यादातर अप्रयुक्त है।
nvogel

@ ड्डपोर्टस - 500 के आईएनडी के साथ बुलाया गया, बी को 50 की कार्रवाई के साथ बुलाया गया - एक्शन - 51 के साथ एक रिटर्न, 52 के साथ बी। आवश्यकता विफल।
होगन

दिलचस्प। मुझे अलग परिणाम मिलते हैं (2008r2 पर)। क्या आप डीडीएल के साथ पूर्ण रिप्रो पोस्ट कर सकते हैं और अपने बिल्ड / संस्करण को बता सकते हैं।
nvogel
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.