Czy istnieje instrukcja SQL pobierająca wartość sekwencji, która jej nie zwiększa.
Dzięki.
EDYCJA I WNIOSEK
Jak stwierdził Justin Cave Nie ma sensu próbować "zapisywać" numeru sekwencji
select a_seq.nextval from dual;
jest wystarczająco dobry, aby sprawdzić wartość sekwencji.
Nadal uważam, że odpowiedź Ollie jest dobra, ponieważ odpowiedziała na pierwsze pytanie. ale zadaj sobie pytanie o konieczność nie modyfikowania sekwencji, jeśli kiedykolwiek zechcesz to zrobić.
nextval
przetestowania sekwencji? Nie zakładasz, że sekwencje będą wolne od luk, prawda? Dlatego „marnowanie” wartości sekwencji nie powinno stanowić problemu.Odpowiedzi:
Można uzyskać wiele metadanych z sekwencji
user_sequences
,all_sequences
adba_sequences
.Te widoki działają w różnych sesjach.
EDYTOWAĆ:
Jeśli sekwencja znajduje się w Twoim domyślnym schemacie, to:
Jeśli chcesz wszystkie metadane, to:
Mam nadzieję, że to pomoże...
EDYCJA2:
Długotrwały sposób na zrobienie tego bardziej niezawodnie, jeśli rozmiar pamięci podręcznej jest inny niż 1, to:
Uważaj tylko, jeśli inni używają sekwencji w tym czasie - oni (lub ty) mogą dostać
Możesz również ustawić pamięć podręczną na
NOCACHE
przed resetowaniem, a następnie przywrócić jej pierwotną wartość, aby upewnić się, że nie zapisałeś wielu wartości w pamięci podręcznej.źródło
ALL_SEQUENCES
to widok. Jeśli nie masz do niego dostępu, spróbuj wybrać,USER_SEQUENCES
jeśli sekwencja znajduje się w Twoim domyślnym schemacie. (Nie będziesz potrzebowaćsequence_owner = '<sequence_owner>'
klauzuli dlaUSER_SEQUENCES
).LAST_NUMBER
WALL_SEQUENCES
nie będzie to ostatni numer, że sesja została rzeczywiście podana i nie będzie to numer, który będzie zwrócony z wywołaniasequence_name.nextval
w ogóle. Zakładając, że ustawiłeś sekwencję naCACHE
więcej niż 1 (domyślnie 20),LAST_NUMBER
będzie ostatnią liczbą znajdującą się w pamięci podręcznej. Nie ma gwarancji, że ten numer kiedykolwiek rzeczywiście zostanie nadany jakiejkolwiek sesji.ALTER SEQUENCE seq INCREMENT BY -1;
będzie problemem, chyba że można zagwarantować , że żadna inna sesja nie zadzwoniseq.nextval
. W przeciwnym razie sekwencja będzie rozdawać zduplikowane wartości, co zwykle nie jest tym, czego się chce.select MY_SEQ_NAME.currval from DUAL;
Pamiętaj, że działa to tylko wtedy, gdy biegałeś
select MY_SEQ_NAME.nextval from DUAL;
w bieżących sesjach.źródło
Moja pierwotna odpowiedź była nieprawidłowa pod względem faktycznym i cieszę się, że została usunięta. Poniższy kod będzie działał w następujących warunkach a) wiesz, że nikt inny nie modyfikował sekwencji b) sekwencja została zmodyfikowana przez twoją sesję. W moim przypadku napotkałem podobny problem, gdy wywoływałem procedurę, która modyfikowała wartość i jestem pewien, że założenie jest prawdziwe.
Niestety, jeśli nie zmodyfikowałeś sekwencji w swojej sesji, uważam, że inni mają rację, twierdząc, że NEXTVAL jest jedyną drogą.
źródło
To nie jest odpowiedź, tak naprawdę i wpisałbym ją jako komentarz, gdyby pytanie nie zostało zablokowane. To odpowiada na pytanie:
Dlaczego miałbyś tego chcieć?
Załóżmy, że masz tabelę z sekwencją jako kluczem podstawowym, a sekwencja jest generowana przez wyzwalacz wstawiania. Jeśli chcesz, aby sekwencja była dostępna do kolejnych aktualizacji rekordu, musisz mieć sposób na wyodrębnienie tej wartości.
Aby upewnić się, że otrzymałeś właściwy, możesz zawrzeć zapytanie INSERT i RonK w transakcji.
Zapytanie RonK:
W powyższym scenariuszu zastrzeżenie RonK nie ma zastosowania, ponieważ wstawianie i aktualizacja miałyby miejsce w tej samej sesji.
źródło
Próbowałem również użyć CURRVAL, w moim przypadku, aby dowiedzieć się, czy jakiś proces wstawił nowe wiersze do jakiejś tabeli z tą sekwencją jako klucz podstawowy. Moje założenie było takie, że CURRVAL będzie najszybszą metodą. Ale a) CurrVal nie działa, po prostu otrzyma starą wartość, ponieważ jesteś w innej sesji Oracle, dopóki nie wykonasz NEXTVAL we własnej sesji. A b) a
select max(PK) from TheTable
jest również bardzo szybkie, prawdopodobnie dlatego, że PK jest zawsze indeksowana. Lubselect count(*) from TheTable
. Wciąż eksperymentuję, ale oba SELECT wydają się szybkie.Nie przeszkadza mi luka w sekwencji, ale w moim przypadku dużo myślałem o ankietach i nie chciałbym pomyśleć o bardzo dużych lukach. Zwłaszcza jeśli prosty SELECT byłby równie szybki.
Wniosek:
źródło