我正在基于少量组合动态创建序列。我如何从这个动态生成的序列中得到nextVal
?
declare
loc_cd varchar2(10);
gr_cd varchar2(10);
seqval number;
seq varchar2(2000);
st varchar2(2000);
v_select varchar2(2000);
begin
loc_cd :='12345';
gr_cd :='99';
seq := 'SE'||loc_cd||gr_cd;
dbms_output.put_line(seq);
st := 'create sequence ' ||seq|| ' minvalue 1 maxvalue 99999999999 start with 1 increment by 1 cache 20' ;
dbms_output.put_line(st);
execute immediate st;
dbms_output.put_line('seq created');
v_select := 'select '||seq||'.nextval from dual';
execute immediate v_select into seqval;
dbms_output.put_line(seqval); --This is ok
dbms_output.put_line( seq.nextval); -- This is not. how to achieve this ?
end;
我在使用seq.nextval
时遇到问题** Invalid refrence to variable SEQ .**
我不想在下面使用
v_select := 'select '||seq||'.nextval from dual';
execute immediate v_select into seqval;
编辑以进一步阐明我想要实现的目标
我有一个tableA,其中包含CONS_NO,LOC_CD,GR_NO和SRNO列,具有数千条记录。 CONS_NO具有唯一的记录,LOC_CD和GR_NO具有相同的值,例如SRNO值从1到1000表示为12345和94。然后另一组LOC_CD和GR_NO的SRNO为1 t0 1000则表示67890和95,具有不连续的CONS_NO,等等。
我需要使用Java在多线程中处理这些LOC_CD和GR_NO集。例如,一组LOC_CD&GR_NO的值为12345和94(在tableA中具有1000条记录)将在10个线程中处理(每个线程的记录数为100)。每个线程将调用一个过程INSERTPROC。在为一组LOC_CD和GR_NO调用多线程之前,我正在动态创建sequecne说SE1234594,并为另一组SE6789095等等。...
对于LOC_CD和GR_NO的set1,来自Java多线程的调用就像..
seq SE1234594 created
procedure INSERTPROC('12345', '94', 1, 100)
procedure INSERTPROC('12345', '94', 101, 200)
.....
procedure INSERTPROC('12345', '94', 901, 1000)
seq SE1234594 dropped.
对于LOC_CD和GR_NO的set2 67890来自Java多线程的调用就像..
seq SE6789095 created
procedure INSERTPROC('67890', '95', 1, 100)
procedure INSERTPROC('67890', '95', 101, 200)
.....
procedure INSERTPROC('67890', '95', 901, 1000)
seq SE6789095 dropped
INSERTPROC的结构如下所示
procedure INSERTPROC(loc_cd IN VARCHAR2, gr_cd IN VARCHAR2, countstrt number, countend number) as
--declration part
begin
insert into tab3 (sr_no, col1, col2)
(select 'SE'||loc_cd||gr_cd.nextval, --how to use seq here ?
col1,
col2 from (select col1, col2 from tableA a, tab1 b where a.SRNO between countstrt and countend /*some more condition */
)
)
end ;
我的问题:如何在Java INSERTPROC程序中使用通过Java代码动态生成且由LOC_CD和GR_NO组合而成的序列
不幸的是,我无法在表tab3上使用rownum和autoincrement,因为如果proc在并行线程中运行,则rownum会生成相同的sr_no,对于下一组LOC_CD和GR_NO的多线程调用,autoincrment不会以1开头。)
答案 0 :(得分:0)
我能够通过创建一个过程来实现我想要的目标,该过程使我nextval
从动态创建的序列中移出。
CREATE OR REPLACE PROCEDURE callSeq(
seqname IN varchar2,
seqval OUT number
)
IS
v_select varchar2(1000);
BEGIN
v_select := 'select '||seqname||'.nextval from dual';
execute immediate v_select into seqval;
/* dbms_output.put_line(seqval);*/
END;
并在INSERTPROC中将此进程用作
CREATE OR REPLACE PROCEDURE INSERTPROC(LOC_CD IN VARCHAR2,
GR_CD IN VARCHAR2,
countstrt in number, countend in number
) is
declare
seqval number;
BEGIN
FOR c IN (select LOC_CD, GR_CD from tableA a, tab1 b where a.SRNO between countstrt and countend /*some more condition */
)
LOOP
callSeq('SE'||c.LOC_CD||c.GR_CD,seqval) ;
insert into tab3 (col1, col2, sr_no) values(c.LC_CD, c.GR_CD ,seqval) ;
END LOOP;
END;
尽管此过程会降低整体性能。但是还是可以的。欢迎对原始解决方案提出任何其他建议。
答案 1 :(得分:0)
我的建议是专门为tab3_seq
使用单个序列tab3
,并让Oracle使用相同的序列来处理并发线程。
CREATE OR REPLACE PROCEDURE insertproc (
loc_cd IN VARCHAR2,
gr_cd IN VARCHAR2,
countstrt IN NUMBER,
countend IN NUMBER
) IS
BEGIN
INSERT INTO tab3 (
sr_no,
col1,
col2
)
SELECT tab3_seq.NEXTVAL, -- This will not overlap while being used by multiple sessions
col1,
col2
FROM tablea a
JOIN --Use proper Join syntax rather than obsolete a,b syntax
tab1 b ON ( a.id = b.id ) --your Join condition
WHERE a.srno BETWEEN countstrt AND countend /*some more condition */
END;
/