2008-09-02 6 views
175

Ich bin auf der Suche nach einer guten Möglichkeit, mehrzeilige Einfügungen in eine Oracle 9-Datenbank durchzuführen. Das Folgende funktioniert in MySQL, scheint aber in Oracle nicht unterstützt zu werden.Die beste Möglichkeit, mehrzeilige Einfügeoperationen in Oracle durchzuführen?

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'); 

Antwort

108

Dies funktioniert in 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 

Die Sache zu erinnern ist, die from dual Anweisung zu verwenden.

(source)

+4

Es auch genannt etwas ist "Insert All" ab 9i – mlathe

+0

Es ist wählerisch, aber die Formatierung macht mehr Sinn, wenn Sie "union all" am Ende jeder Auswahlzeile setzen (mit Ausnahme der letzten). – Jamie

+0

Ein Nachteil dabei ist, dass wir keine 'squerence verwenden können.nextval, wie es in 'union' von' select' verboten ist. Stattdessen können wir mit "INSERT ALL" gehen. –

10

Wenn Sie die Werte, die Sie bereits in einer anderen Tabelle einfügen möchten, dann können Sie aus einer select-Anweisung ein.

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

Andernfalls können Sie eine Reihe von einreihigen Einfügeanweisungen Liste und mehrere Abfragen in der Masse unterwerfen, um die Zeit für etwas zu speichern, die in Oracle und MySQL arbeitet.

@Espo Die Lösung ist auch eine gute, die in Oracle und MySQL funktioniert, wenn Ihre Daten nicht bereits in einer Tabelle sind.

28

Verwenden Sie SQL * Loader. Es braucht ein wenig Aufbau, aber wenn das nicht einmalig ist, ist es das wert.

Tabelle erstellen

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

CSV erstellen

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

Loader Steuerung erstellen

Datei
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-Kommando

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 

bestätigen einfügen

SQL> select * from ldr_test; 

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

SQL> 

SQL * Loader eine Menge von Optionen, und kann so ziemlich jede Textdatei als Eingabe verwenden. Sie können die Daten sogar in Ihre Steuerdatei einbetten, wenn Sie möchten.

Hier ist eine Seite mit weiteren Details ist - ich baue ein einfaches PL/SQL-Block mit einem lokalen Prozedur wie folgt>SQL*Loader

+0

Dies sollte die beste Antwort IMHO, alles andere (für große Aufgaben) ist für die Problemstellung – ropata

+0

Die ID-Spalte in meiner Tabelle ist automatisch generiert. Kann ich das ID-Feld in der Ladersteuerdatei einfach überspringen? –

+0

@Thom, benutze die sequenz.nextval z. 'fruit_id" fruit_seq.nextval "' in der Spaltendefinition – ropata

19

Immer, wenn ich dies tun müssen, um:

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

In Oracle, mehr Zeilen in der Tabelle t mit Spalten col1, col2 und col3 geben Sie die folgenden Syntax verwenden: (?)

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

Ich verstehe nicht, was 'SELECT 1 FROM DUAL' tut. – jameshfisher

+2

Laut [dieser Tutorial-Seite] (http://www.techonthenet.com/sql/insert.php) funktioniert 'SELECT * FROM DUAL' auch. –

+0

@jameshfisher Ich weiß nicht, warum Multiple-Insert die Auswahl aus 'DUAL' erfordert, aber ich kann Ihnen sagen, was' DUAL' ist: [eine vordefinierte Tabelle] (http://en.wikipedia.org/wiki/DUAL_table). Führen Sie 'SELECT * FROM DUAL' aus, um es anzuzeigen. –