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


13

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 sequence.currvalReferenz verwenden kann, aber ich würde es vorziehen, die ID in ordnungsgemäß benannten Variablen zu speichern.

Vielleicht sollte ich das Drehbuch einfach in eine umhüllen, DECLARE ... BEGIN ... END;aber ich hoffe, dass es eine präzisere Möglichkeit gibt, dies zu tun.


Ergänzung 27. Mai 2011 15:31

Es scheint, dass ich auf jeden Fall die Variablen in einem DECLAREBlock 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 zeigt auf die Variablendeklaration.

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 angelegt

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

Antworten:


11

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


8

Sie benötigen einen Block, wenn Sie Variablen deklarieren

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

ENABLED_USER_ID := SEQ.NEXTVAL;

anstatt eine selectAnweisung zu verwenden (obwohl beide funktionieren)

Andere Möglichkeiten, die Werte beizubehalten, umfassen das Speichern in einer Tabelle oder das Erstellen eines Kontexts , aber ich denke, dies sequence.currvalist wirklich die richtige Antwort


7
SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

ENABLED_USER_ID sollte in einen Deklarationsblock gehen oder?
Basilikode

@Xan: Ja, Variablen können nur in einem DECLARE-Abschnitt definiert werden, der wiederum nur gültig ist, wenn Sie einen PL / SQL-Block haben
a_horse_with_no_name

4

Ich denke, Sie können tatsächlich ohne zusätzliche Variablen davonkommen, indem Sie Folgendes verwenden 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);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.