web-dev-qa-db-ja.com

Oracleで、sequence.nextvalを変数に保存して、複数の挿入で再利用するにはどうすればよいですか?

テスト用のデータをいくつかのテーブルに入力するスクリプトを書いています。

次のようなものを書きたいのですが、方法がわかりません(私は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参照ですが、適切な名前の変数にIDを保存することをお勧めします。

たぶん、スクリプトをDECLARE ... BEGIN ... END;しかし、より簡潔な方法があることを望んでいます。


追加2011年5月27日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 11gサーバーでOracle JDBCドライバー(ojdbc14-10.2.0.4.0.jar)を使用して実行しています。

テーブルTEST_USERが作成されました

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

こうなると思います

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

これを行うには、最初のINSERTステートメントの [〜#〜] returning [〜#〜] 句を使用します。

更新:これについて 私のブログ に最近書いている。

10
Gaius

変数を宣言する場合は、ブロックが必要になります

11gでは、 シーケンスのサポートが改善されました なので、次のように使用できます。

ENABLED_USER_ID := SEQ.NEXTVAL;

selectステートメントを使用するのではなく(どちらでも機能します)

値を永続化するための他のオプションには、値をテーブルに保存する、または コンテキストを作成する が含まれますが、sequence.currvalは本当に「正しい答え」です

SELECT seq.nextval 
   INTO ENABLED_USER_ID
FROM dual;

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