คำตอบ:
นี่คือขั้นตอนที่ดีสำหรับการตั้งค่าลำดับใด ๆ ถึง 0 จาก Oracle guru ทอม Kyte การอภิปรายที่ดีเกี่ยวกับข้อดีข้อเสียในลิงค์ด้านล่างด้วย
tkyte@TKYTE901.US.ORACLE.COM>
create or replace
procedure reset_seq( p_seq_name in varchar2 )
is
l_val number;
begin
execute immediate
'select ' || p_seq_name || '.nextval from dual' INTO l_val;
execute immediate
'alter sequence ' || p_seq_name || ' increment by -' || l_val ||
' minvalue 0';
execute immediate
'select ' || p_seq_name || '.nextval from dual' INTO l_val;
execute immediate
'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0';
end;
/
จากหน้านี้: SQL แบบไดนามิกเพื่อรีเซ็ตค่าลำดับ
การอภิปรายที่ดีอีกอย่างก็อยู่ที่นี่: วิธีการรีเซ็ตลำดับได้อย่างไร
execute immediate
เพื่อจับภาพผลลัพธ์ของตัวเลือกที่ส่งคืนได้มากที่สุด 1 แถว นี่คือเอกสารเกี่ยวกับการดำเนินการทันที: docs.oracle.com/cd/B28359_01/appdev.111/b28370/…
'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0';
รีสตาร์ทจริงเป็นไปไม่ได้AFAIK (โปรดแก้ไขฉันถ้าฉันผิด!)
อย่างไรก็ตามหากคุณต้องการตั้งค่าเป็น 0 คุณสามารถลบและสร้างใหม่ได้
หากคุณต้องการตั้งเป็นค่าเฉพาะคุณสามารถตั้งค่า INCREMENT ให้เป็นค่าลบและรับค่าถัดไป
นั่นคือถ้าลำดับของคุณอยู่ที่ 500 คุณสามารถตั้งค่าเป็น 100 ผ่าน
ALTER SEQUENCE serial INCREMENT BY -400;
SELECT serial.NEXTVAL FROM dual;
ALTER SEQUENCE serial INCREMENT BY 1;
นี่คือแนวทางของฉัน:
ตัวอย่าง:
--Drop sequence
DROP SEQUENCE MY_SEQ;
-- Create sequence
create sequence MY_SEQ
minvalue 1
maxvalue 999999999999999999999
start with 1
increment by 1
cache 20;
alter sequence serial restart start with 1;
คุณลักษณะนี้ได้รับการเพิ่มอย่างเป็นทางการใน 18c แต่ไม่สามารถใช้ได้อย่างเป็นทางการใน 12.1
มีความปลอดภัยในการใช้คุณลักษณะที่ไม่มีเอกสารนี้ใน 12.1 แม้ว่าไวยากรณ์จะไม่รวมอยู่ในเอกสารที่เป็นทางการก็ถูกสร้างขึ้นโดยแพคเกจออราเคิลDBMS_METADATA_DIFF ฉันใช้มันหลายครั้งกับระบบการผลิต อย่างไรก็ตามฉันสร้างคำขอ Oracle Service และพวกเขาตรวจสอบว่าไม่ใช่ข้อผิดพลาดของเอกสารคุณลักษณะไม่ได้รับการสนับสนุนอย่างแท้จริง
ใน 18C คุณลักษณะไม่ปรากฏในภาษา SQL ไวยากรณ์ แต่จะรวมอยู่ในคู่มือผู้ดูแลระบบฐานข้อมูลของ
... RESTART START WITH 0 MINVALUE 0
แนวทางของฉันคือการขยายตัวอย่างเล็ก ๆของดั๊กแมน
ส่วนขยายคือ ...
ส่งผ่านค่าเมล็ดเป็นพารามิเตอร์ ทำไม? ฉันชอบที่จะเรียกสิ่งรีเซ็ตลำดับกลับไปยังหมายเลขที่ใช้สูงสุดในตารางบาง ฉันลงเอยด้วยการเรียก proc นี้จากสคริปต์อื่นซึ่งดำเนินการเรียกหลาย ๆ ครั้งสำหรับการเรียงลำดับทั้งกลุ่มการรีเซ็ตค่า nextval กลับไปสู่ระดับหนึ่งซึ่งสูงพอที่จะไม่ทำให้เกิดการละเมิดคีย์หลักที่ฉันใช้ค่าลำดับสำหรับตัวระบุเฉพาะ
นอกจากนี้ยังได้รับเกียรตินิยมก่อนMINVALUE ในความเป็นจริงอาจผลักดันค่าถัดไปสูงกว่าที่เคยถ้าp_valที่ต้องการหรือminvalue ที่มีอยู่สูงกว่าค่าถัดไปปัจจุบันหรือการคำนวณ
ดีที่สุดของทั้งหมดมันสามารถถูกเรียกให้รีเซ็ตเป็นค่าที่ระบุและเพียงแค่รอจนกว่าคุณจะเห็นขั้นตอนการ "แก้ไขลำดับของฉันทั้งหมด" ตอนท้าย
create or replace
procedure Reset_Sequence( p_seq_name in varchar2, p_val in number default 0)
is
l_current number := 0;
l_difference number := 0;
l_minvalue user_sequences.min_value%type := 0;
begin
select min_value
into l_minvalue
from user_sequences
where sequence_name = p_seq_name;
execute immediate
'select ' || p_seq_name || '.nextval from dual' INTO l_current;
if p_Val < l_minvalue then
l_difference := l_minvalue - l_current;
else
l_difference := p_Val - l_current;
end if;
if l_difference = 0 then
return;
end if;
execute immediate
'alter sequence ' || p_seq_name || ' increment by ' || l_difference ||
' minvalue ' || l_minvalue;
execute immediate
'select ' || p_seq_name || '.nextval from dual' INTO l_difference;
execute immediate
'alter sequence ' || p_seq_name || ' increment by 1 minvalue ' || l_minvalue;
end Reset_Sequence;
โพรซีเดอร์นั้นมีประโยชน์ทั้งหมดด้วยตัวมันเอง แต่ตอนนี้เรามาเพิ่มอีกอันที่เรียกมันและระบุทุกอย่างโดยทางโปรแกรมด้วยระเบียบการตั้งชื่อตามลำดับและค้นหาค่าสูงสุดที่ใช้ในตาราง / ฟิลด์ที่มีอยู่ ...
create or replace
procedure Reset_Sequence_to_Data(
p_TableName varchar2,
p_FieldName varchar2
)
is
l_MaxUsed NUMBER;
BEGIN
execute immediate
'select coalesce(max(' || p_FieldName || '),0) from '|| p_TableName into l_MaxUsed;
Reset_Sequence( p_TableName || '_' || p_Fieldname || '_SEQ', l_MaxUsed );
END Reset_Sequence_to_Data;
ตอนนี้เรากำลังปรุงอาหารด้วยแก๊ส!
ขั้นตอนข้างต้นจะตรวจสอบค่าสูงสุดของฟิลด์ในตารางสร้างชื่อลำดับจากคู่ของตาราง / ฟิลด์และเรียกใช้"Reset_Sequence"ด้วยค่าสูงสุดที่รับรู้
ชิ้นสุดท้ายในปริศนานี้และไอซิ่งบนเค้กมาต่อไป ...
create or replace
procedure Reset_All_Sequences
is
BEGIN
Reset_Sequence_to_Data( 'ACTIVITYLOG', 'LOGID' );
Reset_Sequence_to_Data( 'JOBSTATE', 'JOBID' );
Reset_Sequence_to_Data( 'BATCH', 'BATCHID' );
END Reset_All_Sequences;
ในฐานข้อมูลจริงของฉันมีลำดับประมาณหนึ่งร้อยลำดับที่ถูกรีเซ็ตผ่านกลไกนี้ดังนั้นจึงมีการเรียกไปที่Reset_Sequence_to_Dataอีก 97 ครั้งในขั้นตอนนั้น
รักเหรอ? เกลียดมัน? ไม่แยแส?
l_current
อาจเป็นหนึ่งในค่าต่างๆขึ้นอยู่กับโหนดที่สคริปต์จะทำงาน; การเรียกใช้สคริปต์อีกครั้งอาจส่งผลให้เกิดผลลัพธ์ที่แตกต่างกัน ฉันพบว่าฉันวิ่งไปหลายครั้งในที่สุดก็ตัดสินโดยใช้ค่าเฉพาะ
สคริปต์ต่อไปนี้ตั้งค่าลำดับเป็นค่าที่ต้องการ:
กำหนดลำดับที่สร้างขึ้นใหม่ชื่อ PCS_PROJ_KEY_SEQ และตาราง PCS_PROJ:
BEGIN
DECLARE
PROJ_KEY_MAX NUMBER := 0;
PROJ_KEY_CURRVAL NUMBER := 0;
BEGIN
SELECT MAX (PROJ_KEY) INTO PROJ_KEY_MAX FROM PCS_PROJ;
EXECUTE IMMEDIATE 'ALTER SEQUENCE PCS_PROJ_KEY_SEQ INCREMENT BY ' || PROJ_KEY_MAX;
SELECT PCS_PROJ_KEY_SEQ.NEXTVAL INTO PROJ_KEY_CURRVAL FROM DUAL;
EXECUTE IMMEDIATE 'ALTER SEQUENCE PCS_PROJ_KEY_SEQ INCREMENT BY 1';
END;
END;
/
END
คำหลักเพิ่มเติม)
โพรซีเดอร์ที่เก็บนี้รีสตาร์ทลำดับของฉัน:
Create or Replace Procedure Reset_Sequence
is
SeqNbr Number;
begin
/* Reset Sequence 'seqXRef_RowID' to 0 */
Execute Immediate 'Select seqXRef.nextval from dual ' Into SeqNbr;
Execute Immediate 'Alter sequence seqXRef increment by - ' || TO_CHAR(SeqNbr) ;
Execute Immediate 'Select seqXRef.nextval from dual ' Into SeqNbr;
Execute Immediate 'Alter sequence seqXRef increment by 1';
END;
/
มีอีกวิธีในการรีเซ็ตลำดับใน Oracle: ตั้งค่าmaxvalue
และcycle
คุณสมบัติ เมื่อnextval
ลำดับที่มาถึงmaxvalue
ถ้าcycle
คุณสมบัติถูกตั้งค่ามันจะเริ่มต้นอีกครั้งจากminvalue
ลำดับ
ข้อดีของวิธีนี้เมื่อเทียบกับการตั้งค่าลบincrement by
คือลำดับที่สามารถใช้งานต่อไปได้ในขณะที่กระบวนการรีเซ็ตทำงานลดโอกาสที่คุณต้องใช้รูปแบบการหยุดทำงานบางอย่างเพื่อทำการรีเซ็ต
ค่าที่maxvalue
จะต้องมากกว่าปัจจุบันnextval
ดังนั้นขั้นตอนด้านล่างรวมถึงพารามิเตอร์ทางเลือกที่ช่วยให้บัฟเฟอร์ในกรณีที่มีการเข้าถึงลำดับอีกครั้งระหว่างการเลือกnextval
ในขั้นตอนและการตั้งค่าcycle
คุณสมบัติ
create sequence s start with 1 increment by 1;
select s.nextval from dual
connect by level <= 20;
NEXTVAL
----------
1
...
20
create or replace procedure reset_sequence ( i_buffer in pls_integer default 0)
as
maxval pls_integer;
begin
maxval := s.nextval + greatest(i_buffer, 0); --ensure we don't go backwards!
execute immediate 'alter sequence s cycle minvalue 0 maxvalue ' || maxval;
maxval := s.nextval;
execute immediate 'alter sequence s nocycle maxvalue 99999999999999';
end;
/
show errors
exec reset_sequence;
select s.nextval from dual;
NEXTVAL
----------
1
ขั้นตอนในขณะที่ยังคงอนุญาตให้เป็นไปได้ว่าเซสชั่นอื่นจะดึงค่า 0 ซึ่งอาจหรืออาจจะไม่เป็นปัญหาสำหรับคุณ ถ้าเป็นเช่นนั้นคุณสามารถทำได้เสมอ:
minvalue 1
ในการแก้ไขครั้งแรกnextval
ดึงข้อมูลครั้งที่สองnocycle
คุณสมบัติเป็นโพรซีเดอร์อื่นเพื่อให้รันได้ในภายหลังJezus การเขียนโปรแกรมทั้งหมดนี้เป็นเพียงการเริ่มต้นดัชนี ... บางทีฉันอาจเป็นคนงี่เง่า แต่สำหรับ pre-oracle 12 (ซึ่งมีคุณสมบัติการรีสตาร์ท) สิ่งที่ผิดปกติกับ SIMPEL:
drop sequence blah;
create sequence blah
?
1) สมมติว่าคุณสร้างลำดับตามที่แสดงด้านล่าง:
CREATE SEQUENCE TESTSEQ
INCREMENT BY 1
MINVALUE 1
MAXVALUE 500
NOCACHE
NOCYCLE
NOORDER
2) ตอนนี้คุณดึงค่าจาก SEQUENCE ให้บอกว่าฉันได้รับสี่ครั้งตามที่แสดงด้านล่าง
SELECT TESTSEQ.NEXTVAL FROM dual
SELECT TESTSEQ.NEXTVAL FROM dual
SELECT TESTSEQ.NEXTVAL FROM dual
SELECT TESTSEQ.NEXTVAL FROM dual
3) หลังจากรันคำสั่งสี่คำสั่งค่าของ SEQUENCE จะเป็น 4 ทีนี้สมมติว่าฉันได้รีเซ็ตค่าของ SEQUENCE เป็น 1 อีกครั้ง ทำตามขั้นตอนต่อไปนี้ ทำตามขั้นตอนทั้งหมดในลำดับเดียวกันตามที่แสดงด้านล่าง:
ALTER SEQUENCE TESTSEQ INCREMENT BY -3;
SELECT TESTSEQ.NEXTVAL FROM dual
ALTER SEQUENCE TESTSEQ INCREMENT BY 1;
SELECT TESTSEQ.NEXTVAL FROM dual
การเปลี่ยนแปลงค่า INCREMENT ของลำดับเพิ่มขึ้นแล้วเปลี่ยนกลับเป็นค่าที่ไม่เจ็บปวดและคุณจะได้รับประโยชน์เพิ่มเติมโดยไม่ต้องสร้างทุนทั้งหมดอีกครั้งตามที่คุณต้องการให้คุณลบ / สร้างลำดับขึ้นใหม่
ฉันสร้างบล็อกเพื่อรีเซ็ตลำดับทั้งหมดของฉัน:
DECLARE
I_val number;
BEGIN
FOR US IN
(SELECT US.SEQUENCE_NAME FROM USER_SEQUENCES US)
LOOP
execute immediate 'select ' || US.SEQUENCE_NAME || '.nextval from dual' INTO l_val;
execute immediate 'alter sequence ' || US.SEQUENCE_NAME || ' increment by -' || l_val || ' minvalue 0';
execute immediate 'select ' || US.SEQUENCE_NAME || '.nextval from dual' INTO l_val;
execute immediate 'alter sequence ' || US.SEQUENCE_NAME || ' increment by 1 minvalue 0';
END LOOP;
END;
นี่คือขั้นตอนที่มีประสิทธิภาพมากขึ้นสำหรับการแก้ไขค่าถัดไปที่ส่งคืนโดยลำดับรวมทั้งอีกมาก
next_value
จะ! = min_value
และระหว่างและmin_value
max_value
increment_by
ตั้งค่าปัจจุบัน (หรือที่เสนอ) เช่นเดียวกับการตั้งค่าลำดับอื่น ๆ ทั้งหมดเมื่อล้างข้อมูลORA-01403: no data found
ข้อผิดพลาดนี่คือรหัส:
CREATE OR REPLACE PROCEDURE alter_sequence(
seq_name user_sequences.sequence_name%TYPE
, next_value user_sequences.last_number%TYPE := null
, increment_by user_sequences.increment_by%TYPE := null
, min_value user_sequences.min_value%TYPE := null
, max_value user_sequences.max_value%TYPE := null
, cycle_flag user_sequences.cycle_flag%TYPE := null
, cache_size user_sequences.cache_size%TYPE := null
, order_flag user_sequences.order_flag%TYPE := null)
AUTHID CURRENT_USER
AS
l_seq user_sequences%rowtype;
l_old_cache user_sequences.cache_size%TYPE;
l_next user_sequences.min_value%TYPE;
BEGIN
-- Get current sequence settings as defaults
SELECT * INTO l_seq FROM user_sequences WHERE sequence_name = seq_name;
-- Update target settings
l_old_cache := l_seq.cache_size;
l_seq.increment_by := nvl(increment_by, l_seq.increment_by);
l_seq.min_value := nvl(min_value, l_seq.min_value);
l_seq.max_value := nvl(max_value, l_seq.max_value);
l_seq.cycle_flag := nvl(cycle_flag, l_seq.cycle_flag);
l_seq.cache_size := nvl(cache_size, l_seq.cache_size);
l_seq.order_flag := nvl(order_flag, l_seq.order_flag);
IF next_value is NOT NULL THEN
-- Determine next value without exceeding limits
l_next := LEAST(GREATEST(next_value, l_seq.min_value+1),l_seq.max_value);
-- Grab the actual latest seq number
EXECUTE IMMEDIATE
'ALTER SEQUENCE '||l_seq.sequence_name
|| ' INCREMENT BY 1'
|| ' MINVALUE '||least(l_seq.min_value,l_seq.last_number-l_old_cache)
|| ' MAXVALUE '||greatest(l_seq.max_value,l_seq.last_number)
|| ' NOCACHE'
|| ' ORDER';
EXECUTE IMMEDIATE
'SELECT '||l_seq.sequence_name||'.NEXTVAL FROM DUAL'
INTO l_seq.last_number;
l_next := l_next-l_seq.last_number-1;
-- Reset the sequence number
IF l_next <> 0 THEN
EXECUTE IMMEDIATE
'ALTER SEQUENCE '||l_seq.sequence_name
|| ' INCREMENT BY '||l_next
|| ' MINVALUE '||least(l_seq.min_value,l_seq.last_number)
|| ' MAXVALUE '||greatest(l_seq.max_value,l_seq.last_number)
|| ' NOCACHE'
|| ' ORDER';
EXECUTE IMMEDIATE
'SELECT '||l_seq.sequence_name||'.NEXTVAL FROM DUAL'
INTO l_next;
END IF;
END IF;
-- Prepare Sequence for next use.
IF COALESCE( cycle_flag
, next_value
, increment_by
, min_value
, max_value
, cache_size
, order_flag) IS NOT NULL
THEN
EXECUTE IMMEDIATE
'ALTER SEQUENCE '||l_seq.sequence_name
|| ' INCREMENT BY '||l_seq.increment_by
|| ' MINVALUE '||l_seq.min_value
|| ' MAXVALUE '||l_seq.max_value
|| CASE l_seq.cycle_flag
WHEN 'Y' THEN ' CYCLE' ELSE ' NOCYCLE' END
|| CASE l_seq.cache_size
WHEN 0 THEN ' NOCACHE'
ELSE ' CACHE '||l_seq.cache_size END
|| CASE l_seq.order_flag
WHEN 'Y' THEN ' ORDER' ELSE ' NOORDER' END;
END IF;
END;
ในโครงการของฉันเมื่อเกิดขึ้นว่ามีคนป้อนข้อมูลด้วยตนเองโดยไม่ใช้ลำดับดังนั้นฉันต้องรีเซ็ตค่าลำดับด้วยตนเองซึ่งฉันเขียนข้อมูลโค้ด sql ด้านล่าง:
declare
max_db_value number(10,0);
cur_seq_value number(10,0);
counter number(10,0);
difference number(10,0);
dummy_number number(10);
begin
-- enter table name here
select max(id) into max_db_value from persons;
-- enter sequence name here
select last_number into cur_seq_value from user_sequences where sequence_name = 'SEQ_PERSONS';
difference := max_db_value - cur_seq_value;
for counter in 1..difference
loop
-- change sequence name here as well
select SEQ_PERSONS.nextval into dummy_number from dual;
end loop;
end;
โปรดทราบรหัสข้างต้นจะใช้งานได้หากลำดับมีความล่าช้า
คุณสามารถใช้ตัวเลือก CYCLE ที่แสดงด้านล่าง:
CREATE SEQUENCE test_seq
MINVALUE 0
MAXVALUE 100
START WITH 0
INCREMENT BY 1
CYCLE;
ในกรณีนี้เมื่อลำดับถึง MAXVALUE (100) มันจะรีไซเคิลไปยัง MINVALUE (0)
ในกรณีของลำดับที่ลดลงลำดับจะรีไซเคิลไปยัง MAXVALUE
นี่คือวิธีการทำให้ลำดับการเพิ่มอัตโนมัติทั้งหมดตรงกับข้อมูลจริง:
สร้างโพรซีเดอร์เพื่อบังคับใช้ค่าถัดไปตามที่อธิบายไว้แล้วในเธรดนี้:
CREATE OR REPLACE PROCEDURE Reset_Sequence(
P_Seq_Name IN VARCHAR2,
P_Val IN NUMBER DEFAULT 0)
IS
L_Current NUMBER := 0;
L_Difference NUMBER := 0;
L_Minvalue User_Sequences.Min_Value%Type := 0;
BEGIN
SELECT Min_Value
INTO L_Minvalue
FROM User_Sequences
WHERE Sequence_Name = P_Seq_Name;
EXECUTE Immediate 'select ' || P_Seq_Name || '.nextval from dual' INTO L_Current;
IF P_Val < L_Minvalue THEN
L_Difference := L_Minvalue - L_Current;
ELSE
L_Difference := P_Val - L_Current;
END IF;
IF L_Difference = 0 THEN
RETURN;
END IF;
EXECUTE Immediate 'alter sequence ' || P_Seq_Name || ' increment by ' || L_Difference || ' minvalue ' || L_Minvalue;
EXECUTE Immediate 'select ' || P_Seq_Name || '.nextval from dual' INTO L_Difference;
EXECUTE Immediate 'alter sequence ' || P_Seq_Name || ' increment by 1 minvalue ' || L_Minvalue;
END Reset_Sequence;
สร้างขั้นตอนอื่นเพื่อปรับยอดลำดับทั้งหมดด้วยเนื้อหาจริง:
CREATE OR REPLACE PROCEDURE RESET_USER_SEQUENCES_TO_DATA
IS
STMT CLOB;
BEGIN
SELECT 'select ''BEGIN'' || chr(10) || x || chr(10) || ''END;'' FROM (select listagg(x, chr(10)) within group (order by null) x FROM ('
|| X
|| '))'
INTO STMT
FROM
(SELECT LISTAGG(X, ' union ') WITHIN GROUP (
ORDER BY NULL) X
FROM
(SELECT CHR(10)
|| 'select ''Reset_Sequence('''''
|| SEQ_NAME
|| ''''','' || coalesce(max('
|| COL_NAME
|| '), 0) || '');'' x from '
|| TABLE_NAME X
FROM
(SELECT TABLE_NAME,
REGEXP_SUBSTR(WTEXT, 'NEW\.(\S*) IS NULL',1,1,'i',1) COL_NAME,
REGEXP_SUBSTR(BTEXT, '(\.|\s)([a-z_]*)\.nextval',1,1,'i',2) SEQ_NAME
FROM USER_TRIGGERS
LEFT JOIN
(SELECT NAME BNAME,
TEXT BTEXT
FROM USER_SOURCE
WHERE TYPE = 'TRIGGER'
AND UPPER(TEXT) LIKE '%NEXTVAL%'
)
ON BNAME = TRIGGER_NAME
LEFT JOIN
(SELECT NAME WNAME,
TEXT WTEXT
FROM USER_SOURCE
WHERE TYPE = 'TRIGGER'
AND UPPER(TEXT) LIKE '%IS NULL%'
)
ON WNAME = TRIGGER_NAME
WHERE TRIGGER_TYPE = 'BEFORE EACH ROW'
AND TRIGGERING_EVENT = 'INSERT'
)
)
) ;
EXECUTE IMMEDIATE STMT INTO STMT;
--dbms_output.put_line(stmt);
EXECUTE IMMEDIATE STMT;
END RESET_USER_SEQUENCES_TO_DATA;
หมายเหตุ:
ฉันสร้างทางเลือกที่ผู้ใช้ไม่จำเป็นต้องรู้ค่าระบบรับและใช้ตัวแปรเพื่ออัปเดต
--Atualizando sequence da tabela SIGA_TRANSACAO, pois está desatualizada
DECLARE
actual_sequence_number INTEGER;
max_number_from_table INTEGER;
difference INTEGER;
BEGIN
SELECT [nome_da_sequence].nextval INTO actual_sequence_number FROM DUAL;
SELECT MAX([nome_da_coluna]) INTO max_number_from_table FROM [nome_da_tabela];
SELECT (max_number_from_table-actual_sequence_number) INTO difference FROM DUAL;
IF difference > 0 then
EXECUTE IMMEDIATE CONCAT('alter sequence [nome_da_sequence] increment by ', difference);
--aqui ele puxa o próximo valor usando o incremento necessário
SELECT [nome_da_sequence].nextval INTO actual_sequence_number from dual;
--aqui volta o incremento para 1, para que futuras inserções funcionem normalmente
EXECUTE IMMEDIATE 'ALTER SEQUENCE [nome_da_sequence] INCREMENT by 1';
DBMS_OUTPUT.put_line ('A sequence [nome_da_sequence] foi atualizada.');
ELSE
DBMS_OUTPUT.put_line ('A sequence [nome_da_sequence] NÃO foi atualizada, já estava OK!');
END IF;
END;
ขั้นตอนการจัดเก็บที่เหมาะกับฉัน
create or replace
procedure reset_sequence( p_seq_name in varchar2, tablename in varchar2 )
is
l_val number;
maxvalueid number;
begin
execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
execute immediate 'select max(id) from ' || tablename INTO maxvalueid;
execute immediate 'alter sequence ' || p_seq_name || ' increment by -' || l_val || ' minvalue 0';
execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
execute immediate 'alter sequence ' || p_seq_name || ' increment by '|| maxvalueid ||' minvalue 0';
execute immediate 'select ' || p_seq_name || '.nextval from dual' INTO l_val;
execute immediate 'alter sequence ' || p_seq_name || ' increment by 1 minvalue 0';
end;
วิธีใช้โพรซีเดอร์ที่เก็บ:
execute reset_sequence('company_sequence','company');