我有许多可能执行的查询,这些查询将返回两列。在调用的过程之前,不知道实际运行哪些查询。我需要对这些查询中返回的数据进行操作,然后再将它们放入另一个已知的表中。
所以我创建了一个表类型来存储这两个记录。我获取查询,使用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"
我相信数据类型是正确的。我猜这是一个错误,我试图这样做。
编辑:其中一个动态查询的示例。
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'
所以:如何从动态查询中填充临时表,该查询返回相同数据类型的已知数量的列?
答案 0 :(得分:1)
问题是因为您无法直接从集合中进行选择 - 您必须先将其强制转换为表格。 E.g:
SELECT sysdate ,runID, Identifier, Message FROM table(tempTable as THETEMP_TABLE);
但是,不是运行select语句,而是将结果提取到集合中,然后使用集合将行插入表中,为什么不简单地执行insert-as-select?这将节省内存(您不再暂时将结果提取到变量中)并且更快更有效。
E.g。类似的东西:
execute immediate 'insert into runresults (...) select sysdate, :runid, t.* from (' || sqltorun ||') t' using runid;