Итак, вот как я это сделал:
DECLARE
b BLOB;
c CLOB;
n NUMBER;
BEGIN
-- << loop_through_table >>
FOR o IN (SELECT TRIM(LABEL) lbl, REQUEST req FROM REQUEST_TABLE) LOOP
b := o.req;
IF ((b is null) OR (LENGTH(b)=0)) THEN
DBMS_OUTPUT.PUT_LINE(o.lbl || ' : No query found');
CONTINUE;
END IF;
-- Convert the BLOB to text to get the SQL query
DBMS_LOB.CREATETEMPORARY(c,TRUE);
n:=1;
-- << loop_through_blob >>
WHILE (n+32767<=LENGTH(b)) LOOP
DBMS_LOB.WRITEAPPEND(c,32767,UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b,32767,n)));
n:=n+32767;
END LOOP;
DBMS_LOB.WRITEAPPEND(c,length(b)-n+1,UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(b,length(b)-n+1,n)));
-- Execute explain plan
execute immediate 'EXPLAIN PLAN SET STATEMENT_ID=''temp1'' FOR ' || c;
-- Look at the result of the explain plan, and get all the lines of OBJECT_TYPE='TABLE'
-- << loop_through_plan >>
FOR p IN ( SELECT OBJECT_NAME FROM PLAN_TABLE WHERE STATEMENT_ID='temp1' AND OBJECT_TYPE='TABLE') LOOP
DBMS_OUTPUT.PUT_LINE(o.lbl || ', ' || p.OBJECT_NAME);
END LOOP;
execute immediate 'DELETE FROM PLAN_TABLE WHERE STATEMENT_ID=''temp1'' ';
END LOOP;
DBMS_OUTPUT.PUT_LINE('-- Completed --');
END;