Di Oracle bagaimana cara saya menyimpan sequence.nextval dalam variabel untuk digunakan kembali dalam beberapa sisipan?

13

Saya sedang menulis skrip untuk mengisi beberapa tabel dengan data untuk pengujian.

Saya ingin menulis sesuatu seperti yang berikut ini tetapi saya tidak tahu bagaimana melakukannya (saya 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);

Saya tahu saya bisa mengatur ulang kueri dan menggunakan sequence.currvalreferensi, tapi saya lebih suka agar id disimpan dalam variabel bernama benar.

Mungkin saya harus membungkus skrip dalam DECLARE ... BEGIN ... END;tapi saya berharap ada cara yang lebih ringkas untuk melakukannya.


Tambahan 27 Mei 2011 15:31

Tampaknya dalam hal apa pun saya harus mendeklarasikan variabel dalam sebuah DECLAREblok. Jadi saya coba

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

tapi saya mendapatkan kesalahan berikut

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

Itu menunjuk ke deklarasi variabel.

Saya menggunakan java untuk memuat skrip dari file dan menjalankannya menggunakan driver Oracle JDBC (ojdbc14-10.2.0.4.0.jar) pada server Oracle 11g.

Tabel dengan TEST_USER telah dibuat

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

Jawaban:

11

Saya pikir seperti ini

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;
/
bernd_k
sumber
10

Anda akan melakukan ini dengan klausa PENGEMBALIAN dalam INSERTpernyataan pertama Anda .

PEMBARUAN: Terjadi untuk menulis tentang ini di blog saya baru-baru ini.

Gayus
sumber
8

Anda akan membutuhkan blok jika Anda mendeklarasikan variabel

Dengan 11g, dukungan untuk sekuens telah ditingkatkan sehingga Anda dapat menggunakannya seperti:

ENABLED_USER_ID := SEQ.NEXTVAL;

daripada menggunakan selectpernyataan (meskipun keduanya akan bekerja)

Pilihan lain untuk mempertahankan nilai-nilai termasuk menyimpannya ke sebuah tabel atau membuat konteks , tapi saya pikir sequence.currvalini benar-benar 'jawaban yang tepat' di sini

Jack mengatakan coba topanswers.xyz
sumber
7
SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;
seekor kuda tanpa nama
sumber
ENABLED_USER_ID harus masuk dalam blok deklarasi kan?
basilikode
@Xan: ya, variabel hanya dapat didefinisikan di bagian DECLARE yang pada gilirannya hanya valid jika Anda memiliki blok PL / SQL
a_horse_with_no_name
4

Saya pikir Anda benar-benar dapat pergi tanpa variabel tambahan dengan menggunakan 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);
mustaccio
sumber