Последовательность nextval/currval за два сеанса

Настройка: Oracle DB работает на компьютере с Windows

Mac подключен к базе данных, оба в одной сети

Проблема: когда я создал последовательность в SQL Developer, я могу видеть и использовать последовательность в этом сеансе. Если я выйду из системы и войду снова, последовательность все еще там. Но если я попытаюсь использовать последовательность через Python и cx_Oracle, это не сработает. Это также не работает наоборот.

[В SQL Developer: пользователь: uc]

create SEQUENCE seq1;

select seq1.nextval from dual; ---> 1

commit; --› хотя оператор create является методом DDL, на всякий случай

[войти через Python, пользователь: uc]

select seq1.currval from dual;--› ORA-08002 Последовательность seq1.currval не определена в этом сеансе

Код питона:

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)

Ошибка говорит о том, что [seq1] не был определен в этом сеансе, но почему работает следующее:

select seq1.nextval from dual --› возвращает 2

Даже после выпуска этого я не могу использовать seq1.currval

Кстати, select sequence_name from user_sequences возвращает seq1в Python

[как пользователь SYS]

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

--› возвращает ноль строк

Почему seq1 недоступен для программы python?

Примечание. С таблицами все работает нормально.

РЕДАКТИРОВАТЬ: также с заглавными буквами "UC", строки не возвращаются

первый выпуск

по-прежнему не работает


person ben.reisinger    schedule 13.03.2021    source источник


Ответы (3)


Не уверен, как это объяснить. Предыдущие 2 ответа верны, но вы как-то упускаете суть. Во-первых, уберите из уравнения все, что не имеет значения. Клиент Mac на базе данных Windows: не имеет значения. SQLDeveloper против Python: не имеет значения. Единственное, что имеет значение, это то, что вы дважды подключаетесь к базе данных по одной и той же схеме. Вы подключаетесь дважды, это означает, что у вас есть 2 отдельных сеанса, и эти сеансы не знают друг о друге. Оба сеанса имеют доступ к одним и тем же объектам базы данных, поэтому, если вы выполните ddl (например, создадите последовательность), этот объект будет виден в другом сеансе. Теперь к сути вашего вопроса. В документации Oracle указано Использовать или ссылаться к текущему значению последовательности вашего сеанса, ссылайтесь на seq_name.CURRVAL. CURRVAL можно использовать только в том случае, если seq_name.NEXTVAL упоминается в текущем пользовательском сеансе (в текущей или предыдущей транзакции).

У вас есть 2 разных сеанса, поэтому, согласно документации, вы не сможете вызывать seq_name.CURRVAL в сеансе other. Это именно то поведение, которое вы видите.

Вы спросите, почему seq1 недоступен для программы python? Ответ: вы не правы, это доступно для программы python. Вы можете вызвать seq1.NEXTVAL из любого сеанса. Но вы не можете вызвать seq1.NEXTVAL из одного сеанса (SQLDeveloper), а затем вызвать seq1.CURRVAL из другого сеанса (python), потому что именно так работают последовательности, как указано в документации.

Просто чтобы подтвердить, что вы не находитесь в одном и том же сеансе, выполните следующую инструкцию для обоих клиентов (SQLDeveloper и python):

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

Вы заметите, что идентификатор сеанса отличается.

person Koen Lostrie    schedule 13.03.2021

CURRVAL возвращает последний выделенный порядковый номер в текущем сеансе. Так что это работает только тогда, когда мы ранее выполнили NEXTVAL. Таким образом, эти два оператора будут возвращать одно и то же значение при выполнении в одном сеансе:

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

Не совсем понятно, чего вы пытаетесь достичь, но похоже, что ваш код Python выполняет один оператор для соединения, поэтому он не подключается к существующему сеансу.

Этот оператор возвращает нулевые строки...

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

... потому что объекты базы данных в Oracle хранятся в ЗАГЛАВНОМ регистре (по крайней мере, по умолчанию, но разумно придерживаться этого значения по умолчанию. Поэтому вместо этого используйте where username = 'UC'.

person APC    schedule 13.03.2021
comment
Также с заглавными буквами я не получаю возврата, я добавил несколько картинок к исходному вопросу. - person ben.reisinger; 13.03.2021

Python установил новый сеанс. В нем последовательность еще не вызывалась, поэтому ее currval не существует. Сначала вы должны выбрать nextval (который, как вы сказали, вернул 2) - только тогда currval будет иметь смысл.

Говоря это

Даже после этого я не могу использовать seq1.currval

трудно поверить.


Это: select * From v$session where username = 'uc' ничего не вернуло, потому что по умолчанию все объекты хранятся в верхнем регистре, поэтому вы должны были запустить

.... where username = 'UC'

Ну наконец то:

commit; --› хотя оператор create является методом DDL, на всякий случай

Какой дел? Нет кейса. DDL фиксирует. Более того, фиксирует дважды (до и после фактического оператора DDL). Да и фиксировать тоже нечего. Поэтому то, что вы сделали, ненужно и в значительной степени бесполезно.

person Littlefoot    schedule 13.03.2021
comment
Вы говорите, в это трудно поверить, но это правда. Вы правы, это первое seq1.nextval должно быть выполнено, но даже если я это сделаю, это все равно не сработает. Я добавлю фотографии к вопросу. - person ben.reisinger; 13.03.2021