Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

Oracle में अनुक्रम के मान को रीसेट करने की आवश्यकता है

यदि इसका उपयोग किया जा रहा है तो आपको मान को रीसेट क्यों नहीं करना चाहिए इसके कारण:

यदि आपके पास 20 रिकॉर्ड हैं और 5-10 रिकॉर्ड हटा दें तो क्या होगा? आपके बीच में एक गैप है जो क्रम को फिर से सेट करने से हल नहीं होगा। अनुक्रम कभी नहीं होंगे संख्याओं का एक अंतराल मुक्त अनुक्रम उत्पन्न करें, एक परिपूर्ण 1, 2 .. n .

अगर आप .nextval . पर कॉल करते हैं और उस मान का उपयोग न करें जो चला गया . है . क्या आप अनुक्रम को छोड़ने और फिर से बनाने जा रहे हैं? यदि आप एक इंसर्ट शुरू करते हैं और इसे रद्द करते हैं और Oracle आपके द्वारा किए गए कार्यों को वापस लेता है, तो वे मान चले गए हैं . अगर आप nocache . सेट करते हैं तब आपके पास कम अंतराल होंगे लेकिन प्रदर्शन के लिए एक हिट की कीमत पर; क्या यह इसके लायक है?

आपके कैशे को उस संख्या पर सेट किया जाना चाहिए, जिसकी आप किसी भी समय सभी सत्रों में करने की अपेक्षा करते हैं। किसी भी प्रदर्शन के मुद्दों से बचने के लिए। अनुक्रमों को किसी भी ताले आदि के बिना एक सरोगेट कुंजी बनाने का एक बहुत तेज़, स्केलेबल तरीका प्रदान करने के लिए डिज़ाइन किया गया है नहीं धनात्मक पूर्णांकों के समुच्चय को पुन:उत्पन्न करने के लिए।

दिन के अंत में यह जरा भी मायने नहीं रखना चाहिए। यदि आप अपनी तालिका की कुंजी के रूप में एक अखंड अनुक्रम पर भरोसा कर रहे हैं तो आपको अनुक्रमों के बजाय अपने डेटा में समस्या है।

प्रश्न का उत्तर देना:

वास्तव में अपने प्रश्न का उत्तर देने के लिए आपको यह करना होगा:

  1. सबसे पहले, पता करें कि आपकी तालिका में अधिकतम आईडी (अनुक्रम) मान क्या है।
  2. फिर अनुक्रम को छोड़ें और फिर से बनाएं।

अधिकतम मान ज्ञात करने का अर्थ है कि आपको प्रदर्शन के लिए एक और हिट की कीमत पर अनुक्रम को गतिशील रूप से फिर से बनाना होगा।

यदि आप ऐसा होने पर अपनी तालिका में कुछ डालने का प्रयास करते हैं तो यह विफल हो जाएगा, और अनुक्रम का उपयोग करने वाले किसी भी ट्रिगर या अन्य ऑब्जेक्ट को अमान्य कर सकता है:

declare

   l_max_value number;

begin

   select max(id)
     into l_max_value
     from my_table;

   execute immediate 'drop sequence my_sequence_name';

   -- nocache is not recommended if you are inserting more than
   -- one row at a time, or inserting with any speed at all.
   execute immediate 'create sequence my_sequence_name
                           start with ' || l_max_value
                      || ' increment by 1
                           nomaxvalue
                           nocycle
                           nocache';

end;
/

जैसा कि मैंने कहा कि यह अनुशंसित नहीं है और आपको किसी भी अंतराल को अनदेखा करना चाहिए।

अपडेट - उर्फ ​​एक बेहतर उत्तर जेफरी केम्प को धन्यवाद:

दस्तावेज़ीकरण की सिफारिश के विपरीत, जैसा कि जेफरी केम्प ने टिप्पणियों में सुझाव दिया है, ऐसा करने का एक तरीका बिना है अनुक्रम को छोड़ना और फिर से बनाना।

अर्थात्, द्वारा:

  1. अधिकतम id के बीच अंतर निकालना आपकी तालिका में और अनुक्रम का वर्तमान मान।
  2. इस ऋणात्मक संख्या से वृद्धि के क्रम को बदलना
  3. अनुक्रम को फिर से 1 से बढ़ाने के लिए बदलना।

इसका लाभ यह है कि वस्तु अभी भी मौजूद है और ट्रिगर, अनुदान आदि अभी भी बनाए हुए हैं। नकारात्मक पक्ष, जैसा कि मैं देख रहा हूं, यह है कि यदि आपके जैसे ही समय में इस ऋणात्मक संख्या से एक और सत्र बढ़ता है तो आप बहुत दूर जा सकते हैं।

यहाँ एक प्रदर्शन है:

परीक्षण सेट करें:

SQL> create sequence test_seq
  2   start with 1
  3   increment by 1
  4   nomaxvalue
  5   nocycle
  6   nocache;

Sequence created.

SQL>
SQL> create table tmp_test ( id number(16) );

Table created.

SQL>
SQL> declare
  2     l_nextval number;
  3  begin
  4
  5    for i in 1 .. 20 loop
  6       insert into tmp_test values ( test_seq.nextval );
  7    end loop;
  8
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL>
SQL> select test_seq.currval from dual;

   CURRVAL
----------
        20

SQL>
SQL> delete from tmp_test where id > 15;

5 rows deleted.

SQL> commit;

Commit complete.

अनुक्रम पूर्ववत करें

SQL>
SQL> declare
  2
  3     l_max_id number;
  4     l_max_seq number;
  5
  6  begin
  7
  8     -- Get the maximum ID
  9     select max(id) into l_max_id
 10       from tmp_test;
 11
 12     -- Get the current sequence value;
 13     select test_seq.currval into l_max_seq
 14       from dual;
 15
 16     -- Alter the sequence to increment by the difference ( -5 in this case )
.
 17     execute immediate 'alter sequence test_seq
 18                          increment by ' || ( l_max_id - l_max_seq );
 19
 20     -- 'increment' by -5
 21     select test_seq.nextval into l_max_seq
 22       from dual;
 23
 24     -- Change the sequence back to normal
 25     execute immediate 'alter sequence test_seq
 26                          increment by 1';
 27
 28  end;
 29  /

PL/SQL procedure successfully completed.

SQL>
SQL> select test_seq.currval from dual;

   CURRVAL
----------
        15

SQL>


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. pl/sql प्रक्रिया में चर घोषित करते समय वाक्यविन्यास त्रुटि

  2. ओरेकल डेटाबेस 11g एक्सप्रेस संस्करण को स्थापित करने के बाद एक नया डेटाबेस कैसे बनाएं?

  3. Oracle संग्रहीत कार्यविधियों के भीतर पाठ की खोज करना

  4. कोई और एसपीयू

  5. जावा Oracle स्थानीय होस्ट कनेक्शन त्रुटि (ORA-12505)