ORACLE:对象类型集合的插入表值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36112518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:11:28  来源:igfitidea点击:

ORACLE: INSERT INTO Table VALUES of object type collection

oraclecollectionsinsertforall

提问by RafalK

Having created the below types;

创建了以下类型;

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

I want to simply insert the data set into a table;

我想简单地将数据集插入表中;

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;

This one works fine, but is it somehow possible to change the "VALUES" clause to avoid naming each attribute in the source object? I would like something like this:

这个工作正常,但是是否可以以某种方式更改“VALUES”子句以避免命名源对象中的每个属性?我想要这样的东西:

VALUES DATA_SET(REC)

Any help will be much appreciated.

任何帮助都感激不尽。

回答by krokodilko

Assumming that columns in the table TBL_01have the same names as names in the object declaration:

假设表中的列TBL_01与对象声明中的名称具有相同的名称:

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

If TBL_01columns have different names, say X,Y,Z, then change respectively this line:
SELECT OBJ_TYPE( X, Y, Z ) BULK COLLECT ...

如果TBL_01列具有不同的名称,例如 X、Y、Z,则分别更改此行:
SELECT OBJ_TYPE( X, Y, Z ) BULK COLLECT ...



Note: you cannot assign 1into the first field here:

注意:您不能1在此处分配到第一个字段:

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

because the first field FLAGis declared as of type datein the object declaration.
I've replaced 1with sysdatein my example.

因为第一个字段在对象声明中FLAG被声明为类型date
我已经在我的例子中替换1sysdate

回答by APC

We can create tables using object type definitions:

我们可以使用对象类型定义创建表:

SQL> create table TBL_02 of OBJ_TYPE
  2  /

Table created.

SQL> 

There aren't many good reasons to do this, but we can work with the types in our programs.

这样做的理由并不多,但我们可以在我们的程序中使用这些类型。

Here is a little example, starting with the test data

这是一个小例子,从测试数据开始

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> 

Alternatively we can use a PL/SQL object defined against the target table. This uses a regular heap table for TBL_02:

或者,我们可以使用针对目标表定义的 PL/SQL 对象。这对 TBL_02 使用常规堆表:

DECLARE
  type tgt_nt is table of TBL_02%rowtype;
  data_set tgt_nt;
BEGIN
  SELECT sysdate, COL_1, COL_2 
  bulk collect into data_set
  FROM TBL_01;

  FORALL REC IN DATA_SET.FIRST..DATA_SET.LAST
    INSERT INTO TBL_02 
    VALUES DATA_SET(REC)
    ; 
END;
/

回答by rohit purwar

--Rollbaclk--

DROP TYPE TBL_OBJ_TYPE;
DROP TYPE OBJ_TYPE;
DROP TABLE TBL_02;
DROP TABLE TBL_01;

--execute--

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

CREATE TABLE TBL_02
(
   FLAG   DATE,
   NUMB   NUMBER (2, 0),
   VARC   VARCHAR2 (40 BYTE)
);


CREATE TABLE TBL_01
(
   TBL_01_COL0   DATE,
   TBL_01_COL1   NUMBER (2, 0),
   TBL_01_COL2   VARCHAR2 (40 BYTE)
);


INSERT INTO TBL_01
     VALUES (SYSDATE, 1, 'mohit');


INSERT INTO TBL_01
     VALUES (SYSDATE, 2, 'vijay');


INSERT INTO TBL_01
     VALUES (SYSDATE, 3, 'sohan');

COMMIT;


SELECT * FROM TBL_01;


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 (REC.TBL_01_COL0, 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,
                        DATA_SET (REC).NUMB,
                        DATA_SET (REC).VARC);
END;

SELECT * FROM TBL_02;