sql - create - أفضل طريقة لإعادة تعيين تسلسل Oracle إلى القيمة التالية في عمود موجود؟




create sequence in oracle (4)

لسبب ما ، أدخل الناس في الماضي البيانات دون استخدام تسلسل. NEXTVAL. لذلك عندما أذهب إلى استخدام تسلسل. NEXTVAL من أجل ملء جدول ، أحصل على انتهاك PK ، لأن هذا الرقم قيد الاستخدام بالفعل في الجدول.

كيف يمكنني تحديث القيمة التالية بحيث تكون قابلة للاستخدام؟ في الوقت الحالي ، أنا أقوم بإدخال أكثر من مرة حتى تنجح ( INSERT INTO tbl (pk) VALUES (sequence.NEXTVAL) ) ، وهذا يؤدي إلى مزامنة المقطع التالي.


إذا تمكنت من الاعتماد على فترة زمنية يكون فيها الجدول في حالة مستقرة دون وجود أي إدخالات جديدة ، فيجب أن يفعل ذلك (غير مجرب):

DECLARE
  last_used  NUMBER;
  curr_seq   NUMBER;
BEGIN
  SELECT MAX(pk_val) INTO last_used FROM your_table;

  LOOP
    SELECT your_seq.NEXTVAL INTO curr_seq FROM dual;
    IF curr_seq >= last_used THEN EXIT;
    END IF;
  END LOOP;
END;

يمكّنك هذا من الحصول على التسلسل مرة أخرى متزامناً مع الجدول ، دون إسقاط / إعادة إنشاء / إعادة تسلسل. كما أنه لا يستخدم DDL ، لذلك لا يتم تنفيذ أي تعهدات ضمنية. بالطبع ، عليك أن تصطاد وتصفع الناس الذين يصرون على عدم استخدام التسلسل لملء العمود ...


تسمح هاتان العمليتان بإعادة ضبط التسلسل وإعادة تعيين التسلسل استنادًا إلى البيانات الموجودة في جدول (اعتذارات عن اصطلاحات التعليمات البرمجية المستخدمة بواسطة هذا العميل):

CREATE OR REPLACE PROCEDURE SET_SEQ_TO(p_name IN VARCHAR2, p_val IN NUMBER)
AS
   l_num   NUMBER;
BEGIN
   EXECUTE IMMEDIATE 'select ' || p_name || '.nextval from dual' INTO l_num;

   -- Added check for 0 to avoid "ORA-04002: INCREMENT must be a non-zero integer"
   IF (p_val - l_num - 1) != 0
   THEN
      EXECUTE IMMEDIATE 'alter sequence ' || p_name || ' increment by ' || (p_val - l_num - 1) || ' minvalue 0';
   END IF;

   EXECUTE IMMEDIATE 'select ' || p_name || '.nextval from dual' INTO l_num;

   EXECUTE IMMEDIATE 'alter sequence ' || p_name || ' increment by 1 ';

   DBMS_OUTPUT.put_line('Sequence ' || p_name || ' is now at ' || p_val);
END;

CREATE OR REPLACE PROCEDURE SET_SEQ_TO_DATA(seq_name IN VARCHAR2, table_name IN VARCHAR2, col_name IN VARCHAR2)
AS
   nextnum   NUMBER;
BEGIN
   EXECUTE IMMEDIATE 'SELECT MAX(' || col_name || ') + 1 AS n FROM ' || table_name INTO nextnum;

   SET_SEQ_TO(seq_name, nextnum);
END;

مع أوراكل 10.2g:

select  level, sequence.NEXTVAL
from  dual 
connect by level <= (select max(pk) from tbl);

سيقوم بتعيين قيمة التسلسل الحالية إلى الحد الأقصى (pk) لجدولك (أي أن المكالمة التالية إلى NEXTVAL سوف تعطيك النتيجة الصحيحة) ؛ إذا كنت تستخدم العلجوم ، اضغط F5 لتشغيل العبارة ، وليس F9 ، أي الصفحات الإخراج (وبالتالي وقف الزيادة بعد ، عادة ، 500 صف). الجانب الجيد: هذا الحل هو DML فقط ، وليس DDL. فقط SQL ولا PL-SQL. الجانب السيئ: يقوم هذا الحل بطباعة صفوف (pk) من الإنتاج ، أي أبطأ عادة من حل ALTER SEQUENCE.


يمكنك زيادة حجم ذاكرة التخزين المؤقت مؤقتًا والقيام بتحديد دمية واحدة ثم إعادة تعيين حجم ذاكرة التخزين المؤقت إلى 1. على سبيل المثال

ALTER SEQUENCE mysequence INCREMENT BY 100;

select mysequence.nextval from dual;

ALTER SEQUENCE mysequence INCREMENT BY 1;




sequence