En Oracle, ¿cómo guardo una secuencia.nextval en una variable para reutilizarla en múltiples inserciones?


13

Estoy escribiendo un script para llenar algunas tablas con datos para probar.

Me gustaría escribir algo como lo siguiente, pero no sé cómo hacerlo (soy 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);

Sé que podría reorganizar las consultas y usar la sequence.currvalreferencia, pero preferiría que la identificación se guardara en variables con el nombre adecuado.

Tal vez debería envolver el script en un DECLARE ... BEGIN ... END;pero espero que haya una forma más concisa de hacerlo.


Adición 27 de mayo de 2011 15:31

Parece que en cualquier caso tengo que declarar las variables en un DECLAREbloque. Entonces estoy intentando con

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

pero me sale el siguiente error

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

Eso apunta a la declaración de variable.

Estoy usando Java para cargar el script desde un archivo y ejecutarlo usando el controlador JDBC de Oracle (ojdbc14-10.2.0.4.0.jar) en un servidor Oracle 11g.

La tabla TEST_USER se ha creado con

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

Respuestas:


11

Creo que va asi

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

Haría esto con la cláusula RETURNING en su primera INSERTdeclaración.

ACTUALIZACIÓN: Sucedió escribir sobre esto en mi blog recientemente.



7
SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

ENABLED_USER_ID debería ir en un bloque de declaración ¿verdad?
basilikode

@ Xan: sí, las variables solo pueden definirse en una sección DECLARE que a su vez solo es válida si tiene un bloque PL / SQL
a_horse_with_no_name

4

Creo que realmente puedes escapar sin ninguna variable adicional 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);
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.