两个会话中的序列 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 不同。
设置: 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 不同。