Як я можу зберегти послідовність.nextval у змінній Oracle, щоб повторно використовувати її у кількох вставках?


13

Я пишу сценарій для заповнення деяких таблиць даними для тестування.

Я хотів би написати щось на зразок наступного, але я не знаю, як це зробити (я 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);

Я знаю, що я міг би переставити запити та використати sequence.currvalпосилання, але я вважаю за краще, щоб ідентифікатор зберігався у правильно названих змінних.

Можливо, мені слід просто загорнути сценарій, DECLARE ... BEGIN ... END;але я сподіваюся, що є більш стислий спосіб зробити це.


Доповнення 27 травня 2011 15:31

Здається, що в будь-якому випадку я повинен оголосити змінні в DECLAREблоці. Тому я намагаюся

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

але я отримую таку помилку

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

Це вказує на оголошення змінної.

Я використовую Java для завантаження сценарію з файлу і запускаю його за допомогою драйвера Oracle JDBC (ojdbc14-10.2.0.4.0.jar) на сервер Oracle 11g.

Таблиця TEST_USER створена за допомогою

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

Відповіді:


11

Я думаю, що йде так

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

Блок вам знадобиться, якщо ви декларуєте змінні

З 11 г підтримка послідовностей була покращена, щоб ви могли використовувати їх як:

ENABLED_USER_ID := SEQ.NEXTVAL;

а не використовувати selectоператор (хоча обидва будуть працювати)

Інші варіанти збереження значень включають збереження їх у таблиці або створення контексту , але я думаю, що sequence.currvalце справді "правильна відповідь"


7
SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

ENABLED_USER_ID повинен входити в блок оголошення, правильно?
basilikode

@Xan: так, змінні можна визначити лише в розділі DECLARE, що, в свою чергу, справедливий лише в тому випадку, якщо у вас є блок PL / SQL
a_horse_with_no_name

4

Я думаю, що ви можете фактично піти без зайвих змінних, використовуючи 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);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.