从集合类型 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 语句中使用集合 @RajA Insertselect statements 将无法正常工作。然后您可以考虑使用GTT 来保存连接的中间结果。

以上是关于从集合类型 oracle 12c 插入表 - ORA-00902:无效数据类型的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作Redis

python爬虫入门----- 阿里巴巴供应商爬虫

Python词典设置默认值小技巧

《python学习手册(第4版)》pdf

Django settings.py 的media路径设置

Python中的赋值,浅拷贝和深拷贝的区别