首页 文章

如何使用EXECUTE IMMEDIATE填充Oracle中的临时表

提问于
浏览
1

我有许多可能执行的查询,它们将返回两列 . 在调用的过程之前,不知道实际运行哪些查询 . 我需要对这些查询中返回的数据进行操作,然后再将它们放入另一个已知的表中 .

所以我创建了一个表类型来存储这两个记录 . 我获取查询,使用EXECUTE IMMEDIATE,并尝试使用批量收集 . 像这样:

create or replace TYPE TEMP_RECORD IS object (
   Identifier VARCHAR2(5000), 
   Message varchar2(5000)
  );
  /
create or replace TYPE THETEMP_TABLE IS TABLE OF TEMP_RECORD;

DECLARE
  ID NUMBER(38);
  runID NUMBER(38);
  sqlToRun varchar(5000);
  tempTable THETEMP_TABLE;
  CURSOR myCursor IS 
  select ID, SQL FROM QueryTables  
  where IsActive = 1; 

BEGIN

    OPEN myCursor;
    LOOP
    FETCH myCursor INTO id,sqlToRun;

        EXIT WHEN myCursor%notfound; 

        INSERT INTO Run(RunID,StartDateTime)
        VALUES (id,(select sysdate from dual))
        RETURNING ID INTO runID;

       -- dbms_output.PUT_LINE(runID);
        EXECUTE IMMEDIATE sqlToRun BULK COLLECT INTO tempTable;

        INSERT INTO RunResults(RunDate,RunID,SourceID,ResultDescription)
        SELECT (select sysdate from dual),runID, Identifier, Message FROM tempTable;


    END LOOP; 
    CLOSE myCursor ;

END;

问题出在这里: EXECUTE IMMEDIATE sqlToRun BULK COLLECT INTO tempTable;

我收到此错误:

ORA-00932: inconsistent datatypes: expected - got -
ORA-06512: at line 23
00932. 00000 -  "inconsistent datatypes: expected %s got %s"

我相信数据类型是正确的 . 我猜这是一个错误,我试图这样做 .

EDIT: 其中一个动态查询的示例 .

SELECT c.CustomerIdentifier as SourceIdentifier,'Invalid Customer Type record' as InvalidFields
FROM Customer c
WHERE 
c.CustomerType <> 'a' and c.CustomerType <> 'b' and c.CustomerType <> 'b'

所以: How do I populate temporary table from a dynamic query which returns a known amount of columns of the same datatype?

1 回答

  • 1

    问题是因为您无法直接从集合中进行选择 - 您必须先将其转换为表格 . 例如 . :

    SELECT sysdate ,runID, Identifier, Message FROM table(tempTable as THETEMP_TABLE);
    

    但是,不是运行select语句,而是将结果提取到集合中,然后使用集合将行插入表中,为什么不简单地执行insert-as-select?这将节省内存(您不再暂时将结果提取到变量中)并且更快,更高效 .

    例如 . 就像是:

    execute immediate 'insert into runresults (...) select sysdate, :runid, t.* from (' || sqltorun ||') t' using runid;
    

相关问题