Dans Oracle, comment puis-je enregistrer un fichier sequence.nextval dans une variable pour être réutilisé dans plusieurs insertions?


13

J'écris un script pour remplir certaines tables avec des données à tester.

Je voudrais écrire quelque chose comme ceci mais je ne sais pas comment le faire (je suis 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);

Je sais que je pourrais réorganiser les requêtes et utiliser la sequence.currvalréférence, mais je préférerais que l'identifiant soit enregistré dans des variables correctement nommées.

Peut-être que je devrais juste envelopper le script dans un, DECLARE ... BEGIN ... END;mais j'espère qu'il y a une façon plus concise de le faire.


Ajout 27 mai 2011 15:31

Il semble que dans tous les cas je dois déclarer les variables dans un DECLAREbloc. Donc j'essaye avec

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

mais j'obtiens l'erreur suivante

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

Cela pointe vers la déclaration de variable.

J'utilise java pour charger le script à partir d'un fichier et je l'exécute à l'aide du pilote Oracle JDBC (ojdbc14-10.2.0.4.0.jar) sur un serveur Oracle 11g.

La table TEST_USER a été créée avec

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

Réponses:


11

Je pense que ça va comme ça

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;
/


8

Vous aurez besoin d'un bloc si vous déclarez des variables

Avec 11g, le support des séquences a été amélioré afin que vous puissiez les utiliser comme:

ENABLED_USER_ID := SEQ.NEXTVAL;

plutôt que d'utiliser une selectdéclaration (bien que les deux fonctionnent)

D'autres options pour conserver les valeurs incluent les enregistrer dans une table ou créer un contexte , mais je pense que sequence.currvalc'est vraiment la «bonne réponse» ici


7
SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

ENABLED_USER_ID devrait aller dans un bloc de déclaration à droite?
basilikode

@Xan: oui, les variables ne peuvent être définies que dans une section DECLARE qui à son tour n'est valide que si vous avez un bloc PL / SQL
a_horse_with_no_name

4

Je pense que vous pouvez réellement vous en sortir sans variables supplémentaires en utilisant 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);
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.