2

我在尝试使用Execute Immediate包含CREATE TABLE语句和用户定义的表类型的语句时遇到问题。ORA-22905我在 Oracle 11g 上遇到错误。
有什么办法可以解决这个问题吗?

CREATE TYPE MY_TABLE_TYPE AS TABLE OF VARCHAR2(30);  
/  
DECLARE  
    MT MY_TABLE_TYPE;  
BEGIN  
    SELECT * BULK COLLECT INTO MT FROM DUAL;  
    -- Two steps  
    EXECUTE IMMEDIATE 'CREATE TABLE MY_TABLE1 (A VARCHAR2(30))';  
    EXECUTE IMMEDIATE 'INSERT INTO  MY_TABLE1    SELECT * FROM TABLE(:T)' USING MT; -- OK  
    -- One step  
    EXECUTE IMMEDIATE 'CREATE TABLE MY_TABLE2 AS SELECT * FROM TABLE(:T)' USING MT; -- ERROR ORA-22905     
END;  

真正的代码SELECT * FROM TABLE(:T)是动态的(主表名是临时的)并且速度很慢。这就是为什么我尽量避免分两步创建表格(如 完成MY_TABLE1)。还有两个步骤我不能使用SELECT *,但我必须指定所有列(可变数量和超过 100 列)。

4

1 回答 1

0

可能有一种方法可以完全避免这个问题。跳过批量收集并使用简单CREATE TABLE MY_TABLE AS SELECT * FROM DUAL; 的 可能是对收集数据的真实逻辑的过度简化。但几乎总有一种方法可以绕过批量收集并将数据直接存储在一个只用 SQL 的对象中。

如果确实需要 PL/SQL 解决方案,则ORA-22905: cannot access rows from a non-nested table item可以通过创建对象类型并基于该类型创建表来避免错误。这可能无法解决性能问题,但至少这避免了重新指定表 DDL 中所有列的需要。

CREATE TYPE MY_TABLE_OBJECT IS OBJECT
(
    A VARCHAR2(30)
);

CREATE TYPE MY_TABLE_TYPE2 AS TABLE OF VARCHAR2(30);

DECLARE  
    MT MY_TABLE_TYPE2;
BEGIN  
    SELECT * BULK COLLECT INTO MT FROM DUAL;  
    EXECUTE IMMEDIATE 'CREATE TABLE MY_TABLE2 OF MY_TABLE_OBJECT';
    EXECUTE IMMEDIATE 'INSERT INTO  MY_TABLE2 SELECT * FROM TABLE(:T)' USING MT;
END;
/
于 2014-03-13T06:07:37.120 回答