Bir kehanet dizisinin mevcut değerini arttırmadan nasıl alınır?


156

Onu arttırmayan bir dizinin değerini almak için bir SQL talimatı var mı?

Teşekkürler.

DÜZENLEME VE SONUÇ

Justin Cave tarafından belirtildiği gibi sıra numarasını "kaydetmeye" çalışmak yararlı değildir.

select a_seq.nextval from dual;

bir dizi değerini kontrol etmek için yeterince iyidir.

Hala ilk soruyu yanıtladı çünkü Ollie cevap iyi tutmak. ancak kendiniz yapmak istediğinizde diziyi değiştirmemenin gerekliliği hakkında kendinize sorun.


5
Neden? Çözmeye çalıştığınız sorun nedir? Sekansları doğru kullanıyorsanız, başka oturumlara hangi sekans değerlerinin atandığını veya sonraki oturumlara hangi değerlerin atanabileceğini asla önemsememelisiniz.
Justin Cave

3
Veri taşıma işleminden sonra, dizinin taşınan verilere göre doğru bir şekilde güncellendiğinden emin
olunması

3
O zaman nextvaltest etmek için diziyi almanın dezavantajı nedir? Dizilerin boşluk bırakmayacağını düşünmüyorsunuz, değil mi? Bu yüzden bir dizi değerini "boşa harcamak" sorun olmamalı.
Justin Cave

Sanırım haklısın, bu kontrol için db'nin durumunu değiştirmek istemedim ama dürüst olmak gerekirse nedenini bilmiyorum. anlayışınız için teşekkürler. yine de diziyle ilgili eşyalarını öğrendim, hepinize teşekkürler!
frno

Bir dizinin değerini güvenilir bir şekilde alabileceğinizi varsayarsak, dizinin düzgün bir şekilde güncellendiğini kontrol ettiğiniz kehanetiniz nedir?
Shannon Severance

Yanıtlar:


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

Sen sekans meta çeşitli alabilirsiniz user_sequences, all_sequencesve dba_sequences.

Bu görüşler oturumlar boyunca çalışır.

DÜZENLE:

Sekans varsayılan şemanızdaysa:

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

Tüm meta verileri istiyorsanız o zaman:

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

Umarım yardımcı olur...

EDIT2:

Önbellek boyutunuz 1 değilse, daha güvenilir bir şekilde yapmanın uzun bir yolu:

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.

Sadece bu süre zarfında diğerleri diziyi kullanıyorsa - onlar (veya siz)

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

Ayrıca, NOCACHEçok fazla değeri önbelleğe almadığınızdan emin olmak için önbelleği sıfırlamadan önce ve daha sonra orijinal değerine geri ayarlamak isteyebilirsiniz .


Sadece denedim ama bir 'all_sequences' tabloya erişimim yok. Yalnızca yönetici kimlik bilgileriyle gördüğünüz özel bir nesne mi?
frno

1
ALL_SEQUENCESbir görünümdür. Buna erişiminiz USER_SEQUENCESyoksa, sekansın varsayılan şemanızda olup olmadığını seçmeyi deneyin . (İçin sequence_owner = '<sequence_owner>'maddeye ihtiyacınız olmayacak USER_SEQUENCES).
Ollie

15
LAST_NUMBERİçinde ALL_SEQUENCESbir oturum aslında verildi ve bir çağrı dönen olacağını sayı olmayacağını son sayı olmayacaktır sequence_name.nextvalgenelde. Sekansı CACHE1'den fazla olarak ayarladığınızı varsayarsak (varsayılan değer 20'dir), LAST_NUMBERönbellekteki son sayı olacaktır. Bu sayının gerçekte herhangi bir oturuma verileceğinin garantisi yoktur.
Justin Cave

2
ALTER SEQUENCE seq INCREMENT BY -1;başka hiçbir oturumun çağrılamayacağını garanti edemezse sorun olur seq.nextval. Aksi takdirde, sıra yinelenen değerler dağıtır, bu genellikle bir tane istemez.
Shannon Severance

1
OP "Veri taşıma işleminden sonra bir kontrol" demişti, bu yüzden DB'nin genel kullanımda olmadığını varsaymak zor değil ama durum böyle değilse bir sorun olabilir.
Ollie

122

select MY_SEQ_NAME.currval from DUAL;

Yalnızca select MY_SEQ_NAME.nextval from DUAL;geçerli oturumlarda yayınlandığınızda işe yaradığını unutmayın .


1
Cevabınız için çok teşekkürler. Bu Boomi içinde kullanmak zorunda ve yukarı ve aşağı bir çözüm arıyordu
öğrenme ...

0

Orijinal cevabım aslında yanlıştı ve kaldırıldığına sevindim. Aşağıdaki kod aşağıdaki koşullar altında çalışacaktır: a) diziyi başka hiç kimsenin değiştirmediğini bilirsiniz b) dizi oturumunuz tarafından değiştirilmiştir. Benim durumumda, bir değeri değiştiren bir prosedürü çağırdığım benzer bir sorunla karşılaştım ve varsayımın doğru olduğundan eminim.

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

Ne yazık ki, oturumunuzdaki diziyi değiştirmediyseniz, başkalarının NEXTVAL'in tek yol olduğunu belirtmekte haklı olduğuna inanıyorum.


0

Bu bir cevap değil, gerçekten ve soru kilitli olmasaydı bir yorum olarak girerdim. Bu şu soruyu cevaplar:

Neden istiyorsun?

Birincil anahtar olarak sıralı bir tablonuz olduğunu ve sıralamanın bir ekleme tetikleyicisi tarafından oluşturulduğunu varsayın. Sırayı kayda sonraki güncellemeler için kullanılabilir hale getirmek istiyorsanız, bu değeri ayıklamak için bir yolunuz olması gerekir.

Doğru olanı aldığınızdan emin olmak için INSERT ve RonK'nin sorgusunu bir işleme sarmak isteyebilirsiniz.

RonK'ın Sorgusu:

select MY_SEQ_NAME.currval from DUAL;

Yukarıdaki senaryoda, ekleme ve güncelleme aynı oturumda olacağından RonK'ın uyarısı geçerli değildir.


0

Ben de CURRVAL'ı kullanmaya çalıştım, benim durumumda, bazı işlemlerin bu tablodaki Birincil Anahtar olarak bazı tablolara yeni satırlar ekleyip eklemediğini öğrenmek için. Benim varsayım, CURRVAL'in en hızlı yöntem olacağıydı. Ancak a) CurrVal çalışmaz, sadece eski değeri alacaktır çünkü kendi oturumunuzda bir NEXTVAL yapana kadar başka bir Oracle oturumundasınız. Ve b) a select max(PK) from TheTableda çok hızlıdır, muhtemelen bir PK her zaman endekslenir. Veya select count(*) from TheTable. Hala deniyorum, ancak her iki SELECT de hızlı görünüyor.

Bir sıradaki boşluğu umursamıyorum, ama benim durumumda çok fazla yoklamayı düşünüyordum ve çok büyük boşluklar fikrinden nefret ederdim. Özellikle basit bir SELECT kadar hızlı olsaydı.

Sonuç:

  • CURRVAL, başka bir oturumdan NEXTVAL'ı algılamadığı için oldukça işe yaramaz, sadece önceki NEXTVAL'inizden zaten bildiğiniz şeyleri döndürür
  • SELECT MAX (...) FROM ... sıralamanızın bu tabloya bağlı olduğu varsayılarak iyi ve basit bir çözümdür
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.