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
ORACLE: INSERT INTO Table VALUES of object type collection
提问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_01
have 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_01
columns 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 1
into the first field here:
注意:您不能1
在此处分配到第一个字段:
OBJ_TYPE( 1
, REC.TBL_01_COL1
, REC.TBL_01_COL2);
because the first field FLAG
is declared as of type date
in the object declaration.
I've replaced 1
with sysdate
in my example.
因为第一个字段在对象声明中FLAG
被声明为类型date
。
我已经在我的例子中替换1
了sysdate
。
回答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;