2008-09-02 17 views
175

Tôi đang tìm một cách tốt để thực hiện chèn nhiều hàng vào cơ sở dữ liệu Oracle 9. Các công trình sau đây trong MySQL nhưng dường như không được hỗ trợ trong Oracle.Cách tốt nhất để thực hiện chèn nhiều hàng trong Oracle?

INSERT INTO TMP_DIM_EXCH_RT 
(EXCH_WH_KEY, 
EXCH_NAT_KEY, 
EXCH_DATE, EXCH_RATE, 
FROM_CURCY_CD, 
TO_CURCY_CD, 
EXCH_EFF_DATE, 
EXCH_EFF_END_DATE, 
EXCH_LAST_UPDATED_DATE) 
VALUES 
    (1, 1, '28-AUG-2008', 109.49, 'USD', 'JPY', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    (2, 1, '28-AUG-2008', .54, 'USD', 'GBP', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    (3, 1, '28-AUG-2008', 1.05, 'USD', 'CAD', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    (4, 1, '28-AUG-2008', .68, 'USD', 'EUR', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    (5, 1, '28-AUG-2008', 1.16, 'USD', 'AUD', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    (6, 1, '28-AUG-2008', 7.81, 'USD', 'HKD', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'); 

Trả lời

108

này hoạt động trong Oracle:

insert into pager (PAG_ID,PAG_PARENT,PAG_NAME,PAG_ACTIVE) 
      select 8000,0,'Multi 8000',1 from dual 
union all select 8001,0,'Multi 8001',1 from dual 

Những điều cần nhớ ở đây là sử dụng câu lệnh from dual.

(source)

+4

Ngoài ra còn có một cái gì đó gọi là "chèn All" như của 9i – mlathe

+0

Là cầu kỳ, nhưng định dạng có ý nghĩa hơn nếu bạn đặt "công đoàn tất cả" ở cuối mỗi dòng chọn (ngoại trừ cuối cùng). – Jamie

+0

Một bất lợi với điều này là chúng tôi không thể sử dụng một 'sequnce.nextval' vì nó bị cấm trong 'union'of' select'. Thay vào đó chúng ta có thể đi với 'INSERT ALL'. –

10

Nếu bạn có các giá trị mà bạn muốn chèn trong bảng khác đã có, sau đó bạn có thể Chèn từ một tuyên bố chọn.

INSERT INTO a_table (column_a, column_b) SELECT column_a, column_b FROM b_table; 

Nếu không, bạn có thể liệt kê một loạt các câu lệnh chèn hàng và lưu một số truy vấn để làm việc trong cả Oracle và MySQL. Giải pháp của

@Espo cũng là giải pháp tốt sẽ hoạt động trong cả Oracle và MySQL nếu dữ liệu của bạn chưa có trong bảng.

28

Sử dụng trình tải SQL *. Phải mất một chút thiết lập, nhưng nếu đây không phải là một trong những, nó có giá trị nó.

Tạo Bảng

SQL> create table ldr_test (id number(10) primary key, description varchar2(20)); 
Table created. 
SQL> 

Tạo CSV

oracle-2% cat ldr_test.csv 
1,Apple 
2,Orange 
3,Pear 
oracle-2% 

Tạo Loader kiểm soát tập tin

oracle-2% cat ldr_test.ctl 
load data 

infile 'ldr_test.csv' 
into table ldr_test 
fields terminated by "," optionally enclosed by '"'    
(id, description) 

oracle-2% 

Run SQL * Loader lệnh

oracle-2% sqlldr <username> control=ldr_test.ctl 
Password: 

SQL*Loader: Release 9.2.0.5.0 - Production on Wed Sep 3 12:26:46 2008 

Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. 

Commit point reached - logical record count 3 

Confirm chèn

SQL> select * from ldr_test; 

     ID DESCRIPTION 
---------- -------------------- 
     1 Apple 
     2 Orange 
     3 Pear 

SQL> 

SQL * Loader có rất nhiều lựa chọn, và có thể mất khá nhiều bất kỳ tập tin văn bản như đầu vào của nó. Bạn thậm chí có thể nội tuyến dữ liệu trong tập tin điều khiển của bạn nếu bạn muốn.

Đây là một trang web với một số chi tiết ->SQL*Loader

+0

Đây phải là câu trả lời hàng đầu IMHO, bất kỳ điều gì khác (đối với các tác vụ quy mô lớn) đang yêu cầu sự cố – ropata

+0

Cột ID trong bảng của tôi được tự động phát. Tôi có thể bỏ qua trường ID trong tệp điều khiển bộ nạp không? –

+0

@Thom, sử dụng chuỗi.nextval ví dụ: 'fruit_id" fruit_seq.nextval "' trong định nghĩa cột – ropata

19

Bất cứ khi nào tôi cần phải làm điều này tôi xây dựng một/block PL SQL đơn giản với một thủ tục địa phương như thế này:

declare 
    procedure ins 
    is 
     (p_exch_wh_key INTEGER, 
     p_exch_nat_key INTEGER, 
     p_exch_date DATE, exch_rate NUMBER, 
     p_from_curcy_cd VARCHAR2, 
     p_to_curcy_cd VARCHAR2, 
     p_exch_eff_date DATE, 
     p_exch_eff_end_date DATE, 
     p_exch_last_updated_date DATE); 
    begin 
     insert into tmp_dim_exch_rt 
     (exch_wh_key, 
     exch_nat_key, 
     exch_date, exch_rate, 
     from_curcy_cd, 
     to_curcy_cd, 
     exch_eff_date, 
     exch_eff_end_date, 
     exch_last_updated_date) 
     values 
     (p_exch_wh_key, 
     p_exch_nat_key, 
     p_exch_date, exch_rate, 
     p_from_curcy_cd, 
     p_to_curcy_cd, 
     p_exch_eff_date, 
     p_exch_eff_end_date, 
     p_exch_last_updated_date); 
    end; 
begin 
    ins (1, 1, '28-AUG-2008', 109.49, 'USD', 'JPY', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    ins (2, 1, '28-AUG-2008', .54, 'USD', 'GBP', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    ins (3, 1, '28-AUG-2008', 1.05, 'USD', 'CAD', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    ins (4, 1, '28-AUG-2008', .68, 'USD', 'EUR', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    ins (5, 1, '28-AUG-2008', 1.16, 'USD', 'AUD', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'), 
    ins (6, 1, '28-AUG-2008', 7.81, 'USD', 'HKD', '28-AUG-2008', '28-AUG-2008', '28-AUG-2008'); 
end; 
/
263

Trong Oracle, để chèn nhiều hàng vào bảng t với các cột col1, col2 và col3 bạn có thể sử dụng cú pháp sau: (?)

INSERT ALL 
    INTO t (col1, col2, col3) VALUES ('val1_1', 'val1_2', 'val1_3') 
    INTO t (col1, col2, col3) VALUES ('val2_1', 'val2_2', 'val2_3') 
    INTO t (col1, col2, col3) VALUES ('val3_1', 'val3_2', 'val3_3') 
    . 
    . 
    . 
SELECT 1 FROM DUAL; 
+29

Tôi không hiểu 'SELECT 1 FROM DUAL' làm gì. – jameshfisher

+2

Theo [trang hướng dẫn này] (http://www.techonthenet.com/sql/insert.php), 'SELECT * FROM DUAL' cũng hoạt động. –

+0

@jameshfisher Tôi không biết tại sao nhiều-chèn yêu cầu lựa chọn từ 'DUAL', nhưng tôi có thể cho bạn biết những gì' DUAL' là: [một bảng được xác định trước] (http://en.wikipedia.org/wiki/DUAL_table). Chạy 'SELECT * FROM DUAL' để xem nó. –