Получить следующее значение из Oracle Sequence, которая генерируется динамически и в форме varchar2 или строки - PullRequest
0 голосов
/ 31 октября 2018

Я динамически создаю последовательность, основанную на нескольких комбинациях. Как бы я получил 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;

РЕДАКТИРОВАТЬ для получения дополнительной информации о том, чего я хочу достичь

У меня есть таблица A со столбцами CONS_NO, LOC_CD, GR_NO и SRNO, имеющая тысячи записей. CONS_NO имеют уникальные записи, LOC_CD и GR_NO имеют одинаковые значения, скажем, 12345 и 94 для значения SRNO от 1 до 1000., затем другой набор LOC_CD и GR_NO, скажем, 67890 и 95 с SRNO 1 t0 1000 с уникальным CONS_NO и т. Д.

Мне нужно установить эти наборы LOC_CD и GR_NO в многопоточном режиме с использованием Java. Например, набор LOC_CD & GR_NO со значениями 12345 и 94 (имеющий 1000 записей в таблице A) будет обрабатываться в 10 потоках (число записей на поток равно 100). Каждый поток будет вызывать процедуру INSERTPROC. Перед вызовом многопоточности для набора LOC_CD и GR_NO я динамически создаю последовательность, скажем, SE1234594, а также для другого набора SE6789095 и т. Д.

для set1 из LOC_CD и GR_NO, вызовы из многопоточности 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.

для set2 из LOC_CD и GR_NO 67890 95 вызовы из многопоточности 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 и является комбинацией LOC_CD и GR_NO в процедуре INSERTPROC

К сожалению, я не могу использовать rownum и автоинкремент в таблице tab3, так как rownum генерирует то же самое sr_no, если proc выполняется в параллельных потоках, autoincrment не будет начинаться с 1 для следующего набора многопоточных вызовов для LOC_CD и GR_NO.)

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Я предлагаю использовать одну последовательность 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;
/
0 голосов
/ 01 ноября 2018

Я могу достичь того, чего хочу, создав прок, который приносит мне 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;

Хотя этот процесс ухудшает общую производительность. Но это все в порядке. Любые другие предложения оригинального решения приветствуются.

...