2016-03-20 14 views
1

Nach den folgenden Typen erstellt;ORACLE: INSERT INTO WERTE der Objekttypsammlung

CREATE OR REPLACE TYPE OBJ_TYPE AS OBJECT 
    (FLAG  DATE 
    , NUMB  NUMBER(2,0) 
    , VARC  VARCHAR2(40 BYTE)); 
/
CREATE OR REPLACE TYPE TBL_OBJ_TYPE AS TABLE OF OBJ_TYPE; 
/

Ich möchte einfach den Datensatz in eine Tabelle einfügen;

DECLARE 
    DATA_SET TBL_OBJ_TYPE := TBL_OBJ_TYPE(); 
BEGIN 
    FOR REC IN (SELECT * FROM TBL_01) 
    LOOP 
    DATA_SET.EXTEND; 
    DATA_SET(DATA_SET.COUNT) := 
    OBJ_TYPE(1 
      , REC.TBL_01_COL1 
      , REC.TBL_01_COL2); 
    END LOOP; 

    FORALL REC IN DATA_SET.FIRST..DATA_SET.LAST 
    INSERT INTO TBL_02 
    VALUES (DATA_SET(REC).FLAG --listed column 
      , DATA_SET(REC).NUMB --listed column 
      , DATA_SET(REC).VARC); --listed column 
END; 

Dies funktioniert gut, aber ist es irgendwie möglich, die „Werte“ Klausel zu ändern, in dem Quellobjekt zu benennen jedes Attribut zu vermeiden? Ich möchte etwas in der Art:

VALUES DATA_SET(REC) 

Jede Hilfe wird sehr geschätzt.

Antwort

0

Assumming, die Spalten in der Tabelle TBL_01 die gleichen Namen wie Namen in der Objektdeklaration haben:

DECLARE 
    DATA_SET TBL_OBJ_TYPE := TBL_OBJ_TYPE(); 
BEGIN 
    SELECT OBJ_TYPE(sysdate, numb, varc) BULK COLLECT INTO DATA_SET 
    FROM TBL_01; 

    INSERT INTO TBL_02(flag, numb, varc) 
    SELECT * FROM Table(DATA_SET); 
END; 
/

Wenn TBL_01 Spalten unterschiedliche Namen haben, sagen wir X, Y, Z, dann jeweils diese Zeile ändern:
SELECT OBJ_TYPE(X, Y, Z) BULK COLLECT ...


Hinweis: Sie können nicht 1 in das erste Feld hier zuweisen:

OBJ_TYPE(1 
     , REC.TBL_01_COL1 
     , REC.TBL_01_COL2); 

weil das erste Feld FLAG in der Objektdeklaration als vom Typ date deklariert ist.
Ich habe 1 mit sysdate in meinem Beispiel ersetzt.

+0

Hallo kordirko, du bist offensichtlich richtig auf dem Systemdatum, nur vergessen zu ändern. Aber wie auch immer, gibt es einen Weg, dem zu folgen, was ich erwähnt habe; FORALL + INSERT IN Tabelle VALUES -> mit Sammlung ohne Angabe jedes Spaltennamens anstelle der SELECT-Klausel? – RafalK

0

Wir können Tabellen erstellen Objekttyp-Definitionen:

SQL> create table TBL_02 of OBJ_TYPE 
    2/

Table created. 

SQL> 

Es gibt nicht viele gute Gründe, dies zu tun, aber wir können mit den Typen in unseren Programmen arbeiten.

Hier ist ein kleines Beispiel, mit den Daten Test starten

SQL> select * from tbl_01 
    2/

    COL_1 COL_2 
---------- ---------------------------------------- 
     23 ABC 
     42 XYZ 

SQL> DECLARE 
    2  DATA_SET TBL_OBJ_TYPE := TBL_OBJ_TYPE(); 
    3 BEGIN 
    4  FOR REC IN (SELECT * FROM TBL_01) 
    5  LOOP 
    6  DATA_SET.EXTEND; 
    7  DATA_SET(DATA_SET.COUNT) := 
    8  OBJ_TYPE(sysdate 
    9    , REC.COL_1 
10    , REC.COL_2); 
11  END LOOP; 
12 
13  FORALL REC IN DATA_SET.FIRST..DATA_SET.LAST 
14  INSERT INTO TBL_02 
15  VALUES DATA_SET(REC) 
16  ; 
17 END; 
18/ 

PL/SQL procedure successfully completed. 

SQL> select * from tbl_02; 

FLAG   NUMB VARC 
--------- ---------- ---------------------------------------- 
20-MAR-16   23 ABC 
20-MAR-16   42 XYZ 

SQL> 

Alternativ können wir eine PL/SQL-Objekt definiert die Zieltabelle verwenden. Dies verwendet eine normale Heap-Tabelle für TBL_02: