从集合类型 oracle 12c 插入表 - ORA-00902:无效数据类型
Posted
技术标签:
【中文标题】从集合类型 oracle 12c 插入表 - ORA-00902:无效数据类型【英文标题】:Insert into table from collection type oracle 12c - ORA-00902: invalid datatype 【发布时间】:2019-02-26 21:57:52 【问题描述】:我使用的是 Oracle 12.1 我认为我可以查询 12c 中的表类型。当我尝试执行此包时出现错误 ORA-00902: invalid datatype。 我什至尝试使用 cast multiset,但仍然出现同样的错误。
我知道我们可以在数据库级别创建对象然后查询,但我不想这样做。
CREATE OR REPLACE PACKAGE test123 AS
TYPE typ1 IS RECORD(col1 VARCHAR2(100),col2 VARCHAR2(100));
TYPE tab_typ IS TABLE OF typ1 INDEX BY BINARY_INTEGER;
v_tab tab_typ;
PROCEDURE p1;
END;
/
CREATE OR REPLACE PACKAGE BODY test123 AS
PROCEDURE p1 IS
BEGIN
SELECT c1,c2 BULK COLLECT INTO v_tab FROM tabx;
INSERT INTO taby
SELECT * FROM TABLE(v_tab);
END;
END;
/
EXEC test123.p1;
--ORA-00902: invalid datatype
【问题讨论】:
“我知道我们可以在数据库级别创建对象然后查询,但我不想这样做。” - 为什么不呢?此外,如果您只需要执行一个简单的insert into taby(col1,col2) select c1,c2 from tabx
,那么需要收集什么?
不幸的是,为了以您尝试的方式从集合中进行选择,需要在数据库级别定义它。您不能在 SQL 语句中使用本地定义的集合类型。只要您从该包中删除您的类型,而是执行create or replace type typ1 as object (col1 varchar2(100), col2 varchar2(100));
和create or replace type tab_type as table of typ1;
,您的程序就会起作用。在这里查看我的答案:***.com/questions/44683875/…
您的表taby
中有多少列。如果有超过 2 列或这两列的数据类型与 varchar2
不同,则可能会出现问题。但是,假设您的代码中的所有内容都完好无损,它应该可以正常工作,就像在Oracle 12c R1
中查询 plsql 块范围内的类型是非常允许的。再次检查数据库的版本。阅读链接以供参考livesql.oracle.com/apex/livesql/file/…
@XING 感谢及时回复。是的,表中的数据类型:taby 是varchar2 与记录类型相同。你可以自己试试看有没有报错。
@RajA 我已经分享了链接,该链接显示在 PLSQL 范围内声明的 Type
可以在块中的 SQL
语句中使用。你能运行这个语句并与我们分享输出吗Select * from v$version;
。
【参考方案1】:
select * from table 在 Cursor 或 for 循环中可以正常工作,但不能 当我将它用于 INSERT Oracle Database 12c 企业版时 发布 12.1.0.2.0 - 64 位生产 PL/SQL 发布 12.1.0.2.0 - 适用于 Linux 的生产 CORE 12.1.0.2.0 生产 TNS:版本 12.1.0.2.0 - 生产 NLSRTL 版本 12.1.0.2.0 - 生产
仔细查看您的查询后,我发现您是正确的。 Insert
不起作用。它看起来也正确。我们已经有FORALL INSERT
来获取从集合中插入到表中的数据。因此,排除了额外的INSERT as Select Statement
的必要性。但是,您可以使用查询的Where
子句中的集合来使用SELECT
语句。
要制作和插入,您只需按照以下步骤操作。
CREATE OR REPLACE PACKAGE BODY test123
AS
PROCEDURE p1 IS
BEGIN
SELECT c1,c2 BULK COLLECT INTO v_tab FROM tabx;
ForAll rec in 1..v_tab.count
INSERT INTO taby
values v_tab(rec);
--SELECT * FROM TABLE(v_tab);
END;
END;
/
如果您想在Select
语句中使用在PLSQL
范围内声明的Type
,您可以使用如下:
DECLARE
TYPE typ1 IS RECORD(col1 VARCHAR2(100),col2 VARCHAR2(100));
TYPE tab_typ IS TABLE OF typ1 INDEX BY BINARY_INTEGER;
v_tab tab_typ;
BEGIN
SELECT col1,col2 BULK COLLECT INTO v_tab FROM tabx;
DELETE FROM taby
WHERE (col1,col2) in (Select * from table(v_tab));
END;
/
【讨论】:
感谢您的解释。我忘记了 ForAll。谢谢。但在我的情况下,我先填充了集合,然后通过连接和过滤条件对不同的表进行不同的插入。所以我想在 Select 语句中使用集合 @RajAInsert
和 select statements
将无法正常工作。然后您可以考虑使用GTT
来保存连接的中间结果。以上是关于从集合类型 oracle 12c 插入表 - ORA-00902:无效数据类型的主要内容,如果未能解决你的问题,请参考以下文章