1

创建了以下类型;

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

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

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;

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

VALUES DATA_SET(REC)

任何帮助都感激不尽。

4

3 回答 3

1

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

SQL> create table TBL_02 of OBJ_TYPE
  2  /

Table created.

SQL> 

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

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

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> 

或者,我们可以使用针对目标表定义的 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;
/
于 2016-03-20T14:42:04.730 回答
0
--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;
于 2019-02-04T06:21:54.857 回答
0

假设表中的列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;
/

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


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

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

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

于 2016-03-20T10:51:19.640 回答