I'm trying to create a user defined alert for oracle cloud control for long running statements. So that's the reason I can't do some specific actions (like create required table) before clock execution. There is an issue:
Error report -
ORA-06550: line 32, column 10:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 30, column 5:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
When I run this peace of code:
SET SERVEROUTPUT ON
DECLARE
-- VARIABLES
sql_id_var V$SESSION.sql_id%TYPE;
SQL_CHILD_NUMBER_var V$SESSION.SQL_CHILD_NUMBER%TYPE;
ALREADY_EXISTS NUMBER := 0;
--TO GET SQL_ID,CHILD_ID
CURSOR sql_id_cursor IS
select ses.sql_id, ses.SQL_CHILD_NUMBER
from V$SESSION ses
where SES.STATUS = 'ACTIVE'
and SES.USERNAME is not null
--and Ses.AUDSID <> userenv('SESSIONID')
and ses.sql_id is not null
and (SYSDATE - ses.SQL_EXEC_START) > 5/(24*60*60) --SECONDS;
begin
--CREATE TABLE TO STORE SQL_ID OF LONG RUNNING QUERIES
EXECUTE IMMEDIATE 'CREATE TABLE LONG_SQL (SQL_ID VARCHAR2(13),
SQL_CHILD_NUMBER NUMBER,
DETECTED_DATE DATE)' ;
exception when others then
if SQLCODE = -00955 then null;dbms_output.put_line( 'TABLE EXISTS ' ); else raise; end if;
--PROCESSING EVERY LONG QUER
FOR sql_id_row IN sql_id_cursor
LOOP
dbms_output.put_line( 'SQL_ID: ' || sql_id_row.sql_id || ' , SQL_CHILD_NUMBER: ' || sql_id_row.SQL_CHILD_NUMBER || ' , NOW IS :' || SYSDATE);
SELECT COUNT(*)
INTO ALREADY_EXISTS
FROM LONG_SQL
WHERE LONG_SQL.SQL_ID = sql_id_row.sql_id
AND LONG_SQL.SQL_CHILD_NUMBER = sql_id_row.SQL_CHILD_NUMBER;
dbms_output.put_line( 'SQL_ID: ' || sql_id_row.sql_id || ' , SQL_CHILD_NUMBER: ' || sql_id_row.SQL_CHILD_NUMBER || ' , FOUND ' || ALREADY_EXISTS || ' TIMES INTO LOG TABLE');
END LOOP;
end;
/
Within this plsql I create table LONG_SQL if it's not exists and then I want to make some query that uses this new table. Could you suggest something here to workaround it? Is it possible to create and then use table within one plsql block?
Those who live by dynamic SQL, die by dynamic SQL.
If you created table dynamically, you'll have to use it dynamically as well. In other words, this query:
SELECT COUNT(*)
INTO ALREADY_EXISTS
FROM LONG_SQL ...
will also have to be dynamic and executed with execute immediate
.