No Oracle, como salvo um sequence.nextval em uma variável para ser reutilizado em várias inserções?


13

Estou escrevendo um script para preencher algumas tabelas com dados para teste.

Gostaria de escrever algo como o seguinte, mas não sei como fazê-lo (sou Oracle 11g)

SET ENABLED_USER_ID = SEQ.NEXTVAL; // PSEUDOCODE
SET DISABLED_USER_ID = SEQ.NEXTVAL; // PSEUDOCODE

INSERT INTO USERS
        (ID,      USR_NAME)
VALUES  (:ENABLED_USER_ID, 'ANDREW');
INSERT INTO CAR
       (CAR_ID,         CAR_NAME, USR_ID)
VALUES (CARSEQ.NEXTVAL, 'FORD',   :ENABLED_USER_ID);

INSERT INTO USERS
        (ID,      USR_NAME)
VALUES  (:DISABLED_USER_ID, 'ANDREW');
INSERT INTO CAR
       (CAR_ID,         CAR_NAME, USR_ID)
VALUES (CARSEQ.NEXTVAL, 'FORD',   :DISABLED_USER_ID);

Eu sei que poderia reorganizar as consultas e usar a sequence.currvalreferência, mas eu preferiria ter o ID salvo em variáveis ​​nomeadas corretamente.

Talvez eu deva apenas envolver o script de uma forma, DECLARE ... BEGIN ... END;mas espero que exista uma maneira mais concisa de fazê-lo.


Adição 27 maio 2011 15:31

Parece que, em qualquer caso, eu tenho que declarar as variáveis ​​em um DECLAREbloco. Então, eu estou tentando com

DECLARE
  USER_ID NUMBER(10,0) := 1;
BEGIN   
  insert into TEST_USER
  values (user_id, 'andrew', sysdate);   
END;

mas eu recebo o seguinte erro

Caused by: java.sql.SQLException: ORA-06550: **line 2, column 27:**
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

  * & = - + ; < / > at in is mod remainder not rem
  <an exponent (**)> <> or != or ~= >= <= <> and or like like2
  like4 likec between || multiset member submultiset

Isso aponta para a declaração da variável.

Estou usando o java para carregar o script de um arquivo e executando-o usando o driver Oracle JDBC (ojdbc14-10.2.0.4.0.jar) em um servidor Oracle 11g.

A tabela TEST_USER foi criada com

create table TEST_USERS (
    id number(10, 0) not null,
    name varchar2(100),
    date_ins date default sysdate,
    primary key (id)
);

Respostas:


11

Eu acho que é assim

DECLARE
    ENABLED_USER_ID PLS_INTEGER;
    DISABLED_USER_ID PLS_INTEGER;
BEGIN
    ENABLED_USER_ID := SEQ.NEXTVAL;
    DISABLED_USER_ID := SEQ.NEXTVAL;

    INSERT INTO USERS (ID, USR_NAME)
    VALUES  (ENABLED_USER_ID, 'ANDREW');

    INSERT INTO CAR (CAR_ID, CAR_NAME, USR_ID)
    VALUES (CARSEQ.NEXTVAL, 'FORD', ENABLED_USER_ID);

    INSERT INTO USERS (ID, USR_NAME)
    VALUES  (DISABLED_USER_ID, 'ANDREW');

    INSERT INTO CAR (CAR_ID, CAR_NAME, USR_ID)
    VALUES (CARSEQ.NEXTVAL, 'FORD', DISABLED_USER_ID);
END;
/

10

Você faria isso com a cláusula RETURNING em sua primeira INSERTdeclaração.

UPDATE: Recentemente escrevi sobre isso em meu blog .



7
SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

ENABLED_USER_ID deve entrar em um bloco de declaração, certo?
basilikode 27/05

@Xan: sim, as variáveis só podem ser definidos em uma seção DECLARE que por sua vez só é válida se você tem um bloco PL / SQL
a_horse_with_no_name

4

Eu acho que você pode realmente fugir sem nenhuma variável extra usando currval:

INSERT INTO USERS
    (ID,      USR_NAME)
VALUES  (SEQ.NEXTVAL, 'ANDREW');
INSERT INTO CAR
   (CAR_ID,         CAR_NAME, USR_ID)
VALUES (CARSEQ.NEXTVAL, 'FORD',   SEQ.CURRVAL);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.