Trong Oracle, làm cách nào để lưu một chuỗi.nextval trong một biến được sử dụng lại trong nhiều lần chèn?


13

Tôi đang viết một tập lệnh để điền vào một số bảng dữ liệu để thử nghiệm.

Tôi muốn viết một cái gì đó như sau nhưng tôi không biết làm thế nào (Tôi là 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);

Tôi biết tôi có thể sắp xếp lại các truy vấn và sử dụng sequence.currvaltham chiếu, nhưng tôi muốn có id được lưu trong các biến được đặt tên đúng.

Có lẽ tôi chỉ nên bọc kịch bản trong một DECLARE ... BEGIN ... END;nhưng tôi hy vọng có một cách ngắn gọn hơn để làm nó.


Bổ sung 27 tháng 5 năm 2011 15:31

Dường như trong mọi trường hợp tôi phải khai báo các biến trong một DECLAREkhối. Vì vậy, tôi đang cố gắng với

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

nhưng tôi nhận được lỗi sau

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

Điều đó chỉ ra khai báo biến.

Tôi đang sử dụng java để tải tập lệnh từ một tệp và chạy nó bằng trình điều khiển JDBC của Oracle (ojdbc14-10.2.0.4.0.jar) trên máy chủ Oracle 11g.

Bảng TEST_USER đã được tạo bằng

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

Câu trả lời:


11

Tôi nghĩ nó như thế này

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

10

Bạn sẽ làm điều này với mệnh đề RETURNING trong INSERTcâu lệnh đầu tiên của bạn .

CẬP NHẬT: Đã xảy ra để viết về điều này trong blog của tôi gần đây.


8

Bạn sẽ cần một khối nếu bạn đang khai báo các biến

Với 11g, hỗ trợ cho các chuỗi đã được cải thiện để bạn có thể sử dụng chúng như:

ENABLED_USER_ID := SEQ.NEXTVAL;

thay vì sử dụng một selectcâu lệnh (mặc dù cả hai sẽ hoạt động)

Các tùy chọn khác để duy trì các giá trị bao gồm lưu chúng vào bảng hoặc tạo ngữ cảnh , nhưng tôi nghĩ sequence.currvalthực sự là 'câu trả lời đúng' ở đây



4

Tôi nghĩ rằng bạn thực sự có thể thoát khỏi mà không cần thêm bất kỳ biến nào bằng cách sử dụng 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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.