两个会话中的序列 nextval/currval

Sequence nextval/currval in two sessions

设置: windows 机器上的 Oracle DB 运行

Mac与数据库连接,都在同一个网络

问题: 当我在 SQL Developer 中创建一个序列时,我可以在这个会话中看到并使用该序列。如果我注销并再次登录,序列仍然存在。但是如果我尝试通过 Python 和 cx_Oracle 使用序列,它就不起作用。反之亦然。

[在SQL开发者:用户:uc]

create SEQUENCE seq1;

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

commit; --> 虽然create语句是DDL方法,以防万一

[通过Python登录,用户:uc]

select seq1.currval from dual;--> ORA-08002 序列 seq1.currval 未在此会话中定义

python代码:

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 --> returns 2

即使发布了这个,我也不能使用seq1.currval

顺便说一句,select sequence_name from user_sequences returns seq1在 Python

[作为 SYS 用户]

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

--> returns 零行

为什么 seq1 无法访问 python 程序?

注意:使用表格,一切正常

编辑: also with 'UC' being upper case, no rows returned

first issuing

still doesn't work

Python 建立了一个新会话。其中,sequence 还没有被调用,所以它的 currval 不存在。首先你必须 select nextval (正如你所说,返回 2) - 只有这样 currval 才有意义。

这么说

Even after issuing this, I can't use seq1.currval

难以置信。


这:select * From v$session where username = 'uc' 没有返回任何内容,因为 - 默认情况下 - 所有对象都以大写形式存储,所以你应该 运行

.... where username = 'UC'

最后:

commit; --> although the create statement is a DDL method, just in case

哪个案例?没有案例。 DDL 提交。此外,提交两次(在实际 DDL 语句之前和之后)。而且也没有什么可承诺的。因此,你所做的是不必要的,而且几乎没有用。

CURRVAL return是当前会话中最后分配的序列号。所以它只有在我们之前执行过 NEXTVAL 时才有效。所以这两个语句在同一会话中 运行 时将 return 相同的值:

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

尚不完全清楚您要实现的目标,但看起来您的 python 代码正在为连接执行单个语句,因此它没有利用现有会话。

这条语句 return 零行 ...

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

... 因为 Oracle 中的数据库对象以大写形式存储(至少在默认情况下是这样,但坚持使用该默认值是明智的。因此请改用 where username = 'UC'

不知道该如何解释。前 2 个答案是正确的,但不知何故你似乎错过了重点。 首先,把不相关的一切都从等式中剔除。 Mac Windows db 上的客户端:没关系。 SQLDeveloper vs python:没关系。唯一重要的是您以相同模式连接到数据库两次。您连接两次,这意味着您有 2 个独立的会话,而这些会话彼此不了解。两个会话都可以访问相同的数据库对象,因此如果您执行 ddl(例如创建序列),该对象将在另一个会话中可见。 现在是你问题的核心。 oracle documentation 状态 “要使用或引用会话的当前序列值,请引用 seq_name.CURRVAL。只有在当前用户会话(在当前或以前的事务中)引用了 seq_name.NEXTVAL 时才能使用 CURRVAL。 “

您有 2 个不同的会话,因此根据文档,您应该无法在 other 会话中调用 seq_name.CURRVAL。这正是您所看到的行为。

您问“为什么 python 程序无法访问 seq1?”。答案是:你错了,python 程序可以达到。您可以从 任何 会话中调用 seq1.NEXTVAL。但是您不能从一个会话 (SQLDeveloper) 调用 seq1.NEXTVAL,然后从 另一个 会话 (python) 调用 seq1.CURRVAL,因为序列就是这样工作的如文档中所述。

只是为了确认您 不是 在同一个会话中,对两个客户端(SQLDeveloper 和 python)执行以下语句:

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

您会注意到会话 ID 不同。