Tim*_*yer 5 oracle session plsql
我正在编写一个Windows应用程序(在Qt 4.6中) - 在某些时候 - 将1到76000之间的任意数量的数据集插入到某个oracle(10.2)表中.应用程序必须从序列中检索主键或至少主键范围.然后,它将ID存储在列表中,该列表用于批处理执行准备好的查询.
(注意:不应使用触发器,序列也由其他任务使用)
为了避免调用序列X次,我想用X递增序列.
到目前为止我发现的是,在程序中可以使用以下代码:
ALTER SEQUENCE my_sequence INCREMENT BY X;
SELECT my_sequence.CURVAL + 1, my_sequence.NEXTVAL
INTO v_first_number, v_last_number
FROM dual;
ALTER SEQUENCE my_sequence INCREMENT BY 1;
Run Code Online (Sandbox Code Playgroud)
我有两个主要问题:
这个概念是多用户证明吗?或者可能发生以下事情:
Sequence is at 10,000
Session A sets increment to 2,000
Session A selects 10,001 as first and 12,000 as last
Session B sets increment to 5,000
Session A sets increment to 1
Session B selects 12,001 as first and 12,001 as last
Session B sets increment to 1
Run Code Online (Sandbox Code Playgroud)
即使程序相当快,在我的应用程序中也不太可能两个不同的用户几乎同时调用该过程
1)ALTER SEQUENCE是DDL,因此它在语句之前和之后隐式提交.将提交由Windows应用程序启动的数据库事务.如果您使用的是Oracle数据库以外的分布式事务协调器,那么希望事务协调器将提交整个分布式事务,但事务协调器有时会发出它不知道的提交问题.您无法阻止DDL提交.
2)您可以使用多个用户概述的场景.因此,听起来这种方法在您的环境中表现不正确.
您可以使用该DBMS_LOCK包来确保在任何时间点只有一个会话正在调用您的过程,然后从单个SQL语句中调用该序列N次.但是如果其他进程也在使用序列,则无法保证您将获得一组连续的值.
CREATE PROCEDURE some_proc( p_num_rows IN NUMBER,
p_first_val OUT NUMBER,
p_last_val OUT NUMBER )
AS
l_lockhandle VARCHAR2(128);
l_lock_return_code INTEGER;
BEGIN
dbms_lock.allocate_unique( 'SOME_PROC_LOCK',
l_lockhandle );
l_lock_return_code := dbms_lock.request( lockhandle => l_lockhandle,
lockmode => dbms_lock.x_mode,
release_on_commit => true );
if( l_lock_return_code IN (0, 4) ) -- Success or already owned
then
<<do something>>
end if;
dbms_lock.release( l_lockhandle );
END;
Run Code Online (Sandbox Code Playgroud)
在这种情况下改变顺序确实是个坏主意。特别是在多用户环境中。您将提交事务,并且可能会出现一些“竞争条件”数据错误或完整性错误。如果您已经导入了遗留数据并且想要插入带有序列中 id 的新数据,那么这将是合适的。然后您可以更改顺序以将 currval 移动到最大现有...
在我看来,你想从序列中生成 Id。这不需要由
select seq.nextval into l_variable from dual;
insert into table (id, ...) values (l_variable, ....);
Run Code Online (Sandbox Code Playgroud)
您可以直接在插入中使用序列:
insert into table values (id, ...) values (seq.nextval, ....);
Run Code Online (Sandbox Code Playgroud)
并可选择通过以下方式获取分配的值
insert into table values (id, ...) values (seq.nextval, ....)
returning id into l_variable;
Run Code Online (Sandbox Code Playgroud)
即使对于使用 execBatch 进行批量操作也是可能的。要么只是创建 id,要么甚至返回它们。我不确定 java 中的正确语法,但这与行有关
insert into table values (id, ...) values (seq.nextval, ....)
returning id bulk collect into l_cursor;
Run Code Online (Sandbox Code Playgroud)
您将获得一个结果集来浏览分配的号码。