SETUP: Oracle DB działa na maszynie Windows

Mac połączony z bazą danych, zarówno w tej samej sieci

Problem: Kiedy stworzyłem sekwencję w programistom SQL, widzę i użyj sekwencji w tej sesji. Jeśli wyloguję się i znowu logujesz, sekwencja jest nadal tam. Ale jeśli spróbuję użyć sekwencji przez Pythona i CX_Oracle, to nie działa. Nie działa również na odwrót.

[W programistrzu SQL: Użytkownik: UC]

create SEQUENCE seq1;

select seq1.nextval from dual; --- & gt; 1.

commit; - & gt; Chociaż oświadczenie create jest metodą DDL, na wszelki wypadek

[Zaloguj się przez Python, Użytkownik: UC]

select seq1.currval from dual; - & gt; Sekwencja ORA-08002 SEQ1.Currval nie jest zdefiniowany w tej sesji

Kod Pythona:

import cx_Oracle

cx_Oracle.init_oracle_client(lib_dir="/Users/benreisinger/Documents/testclients/instantclient_19_8", config_dir=None, error_url=None, driver_name=None)
# Connect as user "hr" with password "hr" to the "orclpdb" service running on a remote computer.
connection = cx_Oracle.connect("uc", "uc", "10.0.0.22/orcl")

cursor = connection.cursor()
cursor.execute("""
         select seq1.currval from dual
                """)
print(cursor)

for seq1 in cursor:
    print(seq1)

Błąd mówi, że [SEQ1] nie został zdefiniowany w tej sesji, ale dlaczego następująca praca:

select seq1.nextval from dual - & gt; zwraca 2

Nawet po wydaniu tego nie mogę użyć seq1.currval

Btw., select sequence_name from user_sequences zwraca seq1 w Pythonie

[jak użytkownik SYS]

select * from v$session 
    where username = 'uc';

-> Zwraca zero rzędów

Dlaczego seq1 nie jest w zasięgu programu Python?

Uwaga: ze stołami wszystko działa dobrze

EDYTOWAĆ: Również z wielką literą "UC", nie zwrócił wierszy

pierwszy wydawanie

Nadal nie działa

0
ben.reisinger 13 marzec 2021, 20:22

3 odpowiedzi

Najlepsza odpowiedź

Nie wiesz, jak to wyjaśnić. Poprzednie 2 odpowiedzi są poprawne, ale jakoś zdajesz się przegapić. Po pierwsze, weź wszystko, co jest nieistotne z równania. Klient Mac w systemie Windows DB: Nie ma znaczenia. Sqldeveloper vs Python: Nie ma znaczenia. Jedyną rzeczą, która ma znaczenie, jest podłączenie dwukrotnie do bazy danych jako tego samego schematu. Połączasz się dwa razy, oznacza to, że masz 2 oddzielne sesje, a te sesje nie wiedzą o sobie. Oba sesje mają dostęp do tych samych obiektów bazy danych, więc jeśli wykonasz DDL (np. Utwórz sekwencję), obiekt będzie widoczny w innej sesji. Teraz do rdzenia twojego pytania. Dokumentacja Oracle "Aby używać lub odnosić się do bieżącej wartości sekwencji swojej sesji, odniesienie SEQ_NAME.Currval. Currval może być używany tylko wtedy, gdy następuje SEQ_NAME.Nextval została przywołana w bieżącej sesji użytkownika (w bieżącej lub poprzedniej transakcji)."

Masz 2 różne sesje, więc zgodnie z dokumentacją, nie powinieneś być w stanie nazwać SEQ_NAME.Currval w sesji innej . To jest dokładnie zachowanie, które widzisz.

Pytasz "Dlaczego SEQ1 nie jest w zasięgu programu Python?". Odpowiedź brzmi: nie jesteś poprawny, jest w REACH dla programu Python. Możesz zadzwonić seq1.NEXTVAL z sesji dowolnej sesji . Ale nie można wywołać seq1.NEXTVAL z jednej sesji (Sqldeveloper), a następnie wywołaj seq1.CURRVAL z innej sesji (Python), ponieważ właśnie w jaki sposób sekwencje działa zgodnie z dokumentacją.

Aby potwierdzić, że jesteś nie w tej samej sesji, wykonaj następujące oświadczenie dla obu klientów (Sqldeveloper i Python):

select sys_context('USERENV','SID') from dual;

Zauważysz, że identyfikator sesji jest inny.

2
Koen Lostrie 13 marzec 2021, 21:12

Currval zwraca ostatni alokowany numer sekwencji w bieżącej sesji . Działa więc tylko wtedy, gdy wcześniej wykonaliśmy Nextval. Więc te dwa stwierdzenia zwrócą taką samą wartość, gdy biegnie w tej samej sesji:

select seq1.nextval from dual
/
select seq1.currval from dual
/

Nie jest całkowicie jasne, co próbujesz osiągnąć, ale wygląda na to, że kod Pythona wykonuje jedno oświadczenie o połączeniu, więc nie dotykają się istniejącej sesji.

To oświadczenie zwraca zero rzędów ...

select * from v$session 
    where username = 'uc';

... Ponieważ obiekty bazy danych w Oracle są przechowywane w wielkich literach (przynajmniej domyślnie, ale jest mądry, aby trzymać się tego domyślne. Zamiast tego użyj where username = 'UC'.

1
APC 13 marzec 2021, 17:35

Python utworzył nową sesję. W nim kolejność nie została jeszcze wywołana, więc jego currval nie istnieje. Najpierw musisz wybrać nextval (co, jak powiedziałeś, zwrócono 2) - tylko wtedy currval ma sens.

Mówiąc, że

Nawet po wydaniu tego nie mogę użyć SEQ1.Currval

Trudno wierzyć.


To: select * From v$session where username = 'uc' zwrócił nic, ponieważ - domyślnie - wszystkie obiekty są przechowywane w wielkich literach, więc powinieneś pobiegać

.... where username = 'UC'

Wreszcie:

commit; - & gt; Chociaż Utwórz oświadczenie jest metodą DDL, na wszelki wypadek

Który case ? Nie ma obudowy . DDL zobowiązuje się. Ponadto zobowiązuje się dwa razy (przed i po rzeczywistym oświadczeniu DDL). I nie ma też nic do popełnienia. Dlatego to, co zrobiłeś, jest niepotrzebne i prawie bezużyteczne.

0
Littlefoot 13 marzec 2021, 17:34