创建了以下类型;
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)
任何帮助将不胜感激。
我们可以使用对象类型定义创建表:
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;
/
假设表中的列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
。
在我的示例中,我已将1
替换为sysdate
。
--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;