In Oracle come posso salvare un sequence.nextval in una variabile per riutilizzarlo in più inserti?


13

Sto scrivendo uno script per popolare alcune tabelle con i dati per i test.

Vorrei scrivere qualcosa di simile al seguente ma non so come farlo (sono 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);

So che potrei riordinare le query e utilizzare il sequence.currvalriferimento, ma preferirei che l'id fosse salvato in variabili con nome appropriato.

Forse dovrei semplicemente racchiudere la sceneggiatura in un DECLARE ... BEGIN ... END;ma spero che ci sia un modo più conciso per farlo.


Aggiunta 27 maggio 2011 15:31

Sembra che in ogni caso devo dichiarare le variabili in un DECLAREblocco. Quindi ci sto provando

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

ma ottengo il seguente errore

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

Ciò indica la dichiarazione variabile.

Sto usando Java per caricare lo script da un file e eseguirlo utilizzando il driver Oracle JDBC (ojdbc14-10.2.0.4.0.jar) su un server Oracle 11g.

La tabella TEST_USER è stata creata con

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

Risposte:


11

Penso che vada così

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

Lo faresti con la clausola RETURNING nella tua prima INSERTaffermazione.

AGGIORNAMENTO: è successo di scrivere di questo nel mio blog di recente.



7
SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

ENABLED_USER_ID dovrebbe andare in un blocco di dichiarazione giusto?
basilikode,

@Xan: sì, le variabili possono essere definite solo in una sezione DECLARE che a sua volta è valida solo se si dispone di un blocco PL / SQL
a_horse_with_no_name

4

Penso che puoi effettivamente scappare senza ulteriori variabili 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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.