it-swarm.com.de

Wie speichere ich in Oracle eine sequence.nextval in einer Variablen, die in mehreren Einfügungen wiederverwendet werden soll?

Ich schreibe ein Skript, um einige Tabellen mit Daten zum Testen zu füllen.

Ich würde gerne etwas wie das Folgende schreiben, aber ich weiß nicht, wie ich es machen soll (ich bin 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);

Ich weiß, dass ich die Abfragen neu anordnen und die Referenz sequence.currval Verwenden könnte, aber ich würde es vorziehen, die ID in richtig benannten Variablen zu speichern.

Vielleicht sollte ich das Skript einfach in einen DECLARE ... BEGIN ... END; Umschließen, aber ich hoffe, dass es einen prägnanteren Weg gibt, dies zu tun.


Ergänzung 27. Mai 2011 15:31

Es scheint, dass ich auf jeden Fall die Variablen in einem DECLARE -Block deklarieren muss. Also versuche ich es mit

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

aber ich bekomme folgenden Fehler

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

Das weist auf die Variablendeklaration hin.

Ich verwende Java, um das Skript aus einer Datei zu laden und es mit dem Oracle JDBC-Treiber (ojdbc14-10.2.0.4.0.jar) auf einem Oracle 11g-Server auszuführen.

Die Tabelle TEST_USER wurde mit erstellt

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

Ich denke es geht so

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

Sie würden dies mit der Klausel RETURN in Ihrer ersten INSERT -Anweisung tun.

UPDATE: Zufällig habe ich kürzlich in mein Blog darüber geschrieben.

10
Gaius

Sie benötigen einen Block, wenn Sie Variablen deklarieren

Mit 11g, die Unterstützung für Sequenzen wurde verbessert , sodass Sie sie wie folgt verwenden können:

ENABLED_USER_ID := SEQ.NEXTVAL;

anstatt eine select Anweisung zu verwenden (obwohl beide funktionieren werden)

Andere Optionen zum Beibehalten der Werte umfassen das Speichern in einer Tabelle oder Erstellen eines Kontexts , aber ich denke sequence.currval ist hier wirklich die 'richtige Antwort'

SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

Ich denke, Sie können tatsächlich ohne zusätzliche Variablen davonkommen, indem Sie currval verwenden:

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);
4
mustaccio