วิธีการเรียกคืนค่าปัจจุบันของลำดับ oracle โดยไม่เพิ่มขึ้น?


156

มีคำสั่ง SQL เพื่อดึงค่าลำดับที่ไม่เพิ่มขึ้นหรือไม่

ขอบคุณ

แก้ไขและข้อสรุป

ดังที่จัสตินเคฟระบุไว้ไม่มีประโยชน์ที่จะลอง "บันทึก" หมายเลขลำดับ

select a_seq.nextval from dual;

ดีพอที่จะตรวจสอบค่าลำดับ

ฉันยังคงรักษาคำตอบของโอลลี่ไว้เป็นคำตอบที่ดีเพราะมันตอบคำถามเริ่มต้น แต่ถามตัวเองเกี่ยวกับความจำเป็นที่จะไม่แก้ไขลำดับหากคุณต้องการทำมัน


5
ทำไม? ปัญหาที่คุณพยายามแก้ไขคืออะไร หากคุณใช้ลำดับอย่างถูกต้องคุณไม่ควรสนใจว่าจะมีการกำหนดค่าลำดับใดให้กับเซสชันอื่นหรืออาจใช้ค่าใดกับเซสชันถัดไป
Justin Cave

3
เป็นการตรวจสอบหลังจากการโยกย้ายข้อมูลเพื่อให้แน่ใจว่ามีการอัปเดตลำดับอย่างถูกต้องตามข้อมูลที่โอนย้าย
frno

3
แล้วอะไรคือข้อเสียที่จะทำให้nextvalลำดับนั้นเป็นแบบทดสอบ? คุณไม่ได้สมมติว่าลำดับจะไม่มีช่องว่างใช่ไหม? ดังนั้น "เสีย" ค่าลำดับไม่ควรเป็นปัญหา
Justin Cave

ฉันเดาว่าคุณพูดถูกฉันไม่ต้องการเปลี่ยนสถานะของฐานข้อมูลสำหรับเช็คนั้น แต่บอกตามตรงฉันไม่รู้ว่าทำไม ขอบคุณสำหรับความเข้าใจของคุณ อย่างไรก็ตามฉันได้เรียนรู้เนื้อหาของคุณเกี่ยวกับการจัดลำดับแล้วขอบคุณทุกคน!
frno

สมมติว่าคุณสามารถรับค่าของลำดับได้อย่างเชื่อถือได้ Oracle ของคุณที่คุณกำลังตรวจสอบว่าลำดับนั้นได้รับการปรับปรุงอย่างถูกต้องคืออะไร?
Shannon Severance

คำตอบ:


173
SELECT last_number
  FROM all_sequences
 WHERE sequence_owner = '<sequence owner>'
   AND sequence_name = '<sequence_name>';

คุณจะได้รับความหลากหลายของเมตาดาต้าลำดับจากuser_sequences, และall_sequencesdba_sequences

มุมมองเหล่านี้ทำงานข้ามเซสชัน

แก้ไข:

หากลำดับอยู่ในสคีมาเริ่มต้นของคุณ:

SELECT last_number
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

หากคุณต้องการข้อมูลเมตาทั้งหมด:

SELECT *
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

หวังว่ามันจะช่วย ...

EDIT2:

วิธีที่ยืดยาวในการทำอย่างน่าเชื่อถือมากขึ้นถ้าขนาดแคชของคุณไม่ใช่ 1 จะเป็น:

SELECT increment_by I
  FROM user_sequences
 WHERE sequence_name = 'SEQ';

      I
-------
      1

SELECT seq.nextval S
  FROM dual;

      S
-------
   1234

-- Set the sequence to decrement by 
-- the same as its original increment
ALTER SEQUENCE seq 
INCREMENT BY -1;

Sequence altered.

SELECT seq.nextval S
  FROM dual;

      S
-------
   1233

-- Reset the sequence to its original increment
ALTER SEQUENCE seq 
INCREMENT BY 1;

Sequence altered.

เพียงแค่ระวังว่าหากผู้อื่นใช้ลำดับในช่วงเวลานี้พวกเขา (หรือคุณ) อาจได้รับ

ORA-08004: sequence SEQ.NEXTVAL goes below the sequences MINVALUE and cannot be instantiated

นอกจากนี้คุณอาจต้องการตั้งค่าแคชให้เป็นNOCACHEก่อนการตั้งค่าใหม่จากนั้นกลับสู่ค่าเดิมหลังจากนั้นเพื่อให้แน่ใจว่าคุณไม่ได้แคชค่าจำนวนมาก


ลองแล้ว แต่ฉันไม่สามารถเข้าถึงตาราง 'all_sequences' เป็นวัตถุพิเศษที่คุณเห็นด้วยข้อมูลประจำตัวของผู้ดูแลระบบหรือไม่
frno

1
ALL_SEQUENCESคือมุมมอง หากคุณไม่มีสิทธิ์เข้าถึงลองเลือกจากUSER_SEQUENCESหากลำดับอยู่ในสคีมาเริ่มต้นของคุณ (คุณไม่จำเป็นต้องมีsequence_owner = '<sequence_owner>'ข้อสำหรับUSER_SEQUENCES)
โอลลี่

15
LAST_NUMBERในALL_SEQUENCESจะไม่เป็นหมายเลขสุดท้ายที่เซสชั่นที่ได้รับจริงและจะไม่เป็นหมายเลขที่จะกลับมาจากการเรียกร้องให้sequence_name.nextvalในทั่วไป สมมติว่าคุณได้ตั้งค่าลำดับCACHEมากกว่า 1 (ค่าเริ่มต้นคือ 20) LAST_NUMBERจะเป็นหมายเลขสุดท้ายที่อยู่ในแคช ไม่มีการรับประกันว่าจะมีการให้หมายเลขนี้กับเซสชันใด ๆ
Justin Cave

2
ALTER SEQUENCE seq INCREMENT BY -1;เป็นไปได้ที่จะมีปัญหาถ้าผู้ใดสามารถรับประกันได้ว่าไม่มีเซสชั่นอื่น ๆ seq.nextvalที่จะเรียก มิฉะนั้นลำดับจะแจกค่าซ้ำซึ่งมักจะไม่ใช่สิ่งที่ต้องการ
Shannon Severance

1
OP บอกว่า "มันเป็นการตรวจสอบหลังจากการโยกย้ายข้อมูล" ดังนั้นจึงไม่ใช่เรื่องยากที่จะคิดว่าฐานข้อมูลนั้นไม่ใช่การใช้งานทั่วไป แต่อาจเป็นปัญหาหากนี่ไม่ใช่กรณี
โอลลี่

122

select MY_SEQ_NAME.currval from DUAL;

โปรดทราบว่าจะใช้งานได้เฉพาะเมื่อคุณทำงานselect MY_SEQ_NAME.nextval from DUAL;ในเซสชันปัจจุบัน


1
ขอบคุณสำหรับคำตอบของคุณ ฉันต้องใช้สิ่งนี้ภายใน Boomi และกำลังมองหาวิธีแก้ปัญหาขึ้นและลง
การเรียนรู้ ...

0

คำตอบดั้งเดิมของฉันไม่ถูกต้องตามข้อเท็จจริงและฉันดีใจที่มันถูกลบ รหัสด้านล่างจะทำงานภายใต้เงื่อนไขดังต่อไปนี้ก) คุณรู้ว่าไม่มีใครแก้ไขลำดับข) ลำดับของคุณได้รับการแก้ไข ในกรณีของฉันฉันพบปัญหาที่คล้ายกันซึ่งฉันเรียกขั้นตอนที่ปรับเปลี่ยนค่าและฉันมั่นใจว่าสมมติฐานเป็นจริง

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

น่าเศร้าถ้าคุณไม่ได้แก้ไขลำดับในเซสชั่นของคุณฉันเชื่อว่าคนอื่นถูกต้องในการระบุว่า NEXTVAL เป็นวิธีเดียวที่จะไป


0

นี่ไม่ใช่คำตอบจริงๆและฉันจะป้อนมันเป็นความคิดเห็นหากคำถามไม่ถูกล็อค คำถามนี้ตอบคำถาม:

ทำไมคุณต้องการมัน

สมมติว่าคุณมีตารางที่มีลำดับเป็นคีย์หลักและลำดับที่สร้างขึ้นโดยทริกเกอร์แทรก หากคุณต้องการให้มีลำดับสำหรับการอัปเดตระเบียนต่อไปคุณจะต้องมีวิธีในการแยกค่านั้น

เพื่อให้แน่ใจว่าคุณได้รับสิ่งที่ถูกต้องคุณอาจต้องการห่อคำสั่ง INSERT และ RonK ในธุรกรรม

ข้อความค้นหาของ RonK:

select MY_SEQ_NAME.currval from DUAL;

ในสถานการณ์ข้างต้นข้อแม้ของ RonK ใช้ไม่ได้เนื่องจากการแทรกและการอัปเดตจะเกิดขึ้นในเซสชันเดียวกัน


0

ฉันยังพยายามใช้ CURRVAL ในกรณีของฉันเพื่อดูว่าบางกระบวนการแทรกแถวใหม่ลงในบางตารางโดยมีลำดับนั้นเป็นคีย์หลักหรือไม่ สมมติฐานของฉันคือ CURRVAL จะเป็นวิธีที่เร็วที่สุด แต่ก) CurrVal ใช้งานไม่ได้จะเพิ่งได้รับค่าเก่าเพราะคุณอยู่ในเซสชั่น Oracle อีกจนกว่าคุณจะทำ NEXTVAL ในเซสชั่นของคุณเอง และ b) a select max(PK) from TheTableนั้นเร็วมากอาจเป็นเพราะ PK นั้นทำดัชนีอยู่เสมอ select count(*) from TheTableหรือ ฉันยังคงทดลองใช้ แต่ทั้งสองเลือกอย่างรวดเร็ว

ฉันไม่สนใจช่องว่างในลำดับ แต่ในกรณีของฉันฉันคิดว่าจะลงคะแนนเป็นจำนวนมากและฉันจะเกลียดความคิดเกี่ยวกับช่องว่างขนาดใหญ่มาก โดยเฉพาะอย่างยิ่งถ้าเลือกง่ายจะเป็นไปอย่างรวดเร็ว

สรุป:

  • CURRVAL นั้นไร้ประโยชน์เพราะมันไม่ได้ตรวจพบ NEXTVAL จากเซสชั่นอื่นมันกลับเฉพาะสิ่งที่คุณรู้จาก NEXTVAL ก่อนหน้าของคุณ
  • SELECT MAX (... ) จาก ... เป็นทางออกที่ดีเรียบง่ายและรวดเร็วโดยสมมติว่าลำดับของคุณเชื่อมโยงกับตารางนั้น
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.