On a client's database (which I do not have physical access to) we are getting some strange results when joining to a function.
I was able to guide them to replicate the issue on a completely new schema within the same database.
create or replace function GEN_FILENAME(p_file_name varchar2) return varchar2
is
l_filename varchar2(100);
begin
l_filename := 'Test' || '/' || 'Test' || '.' || initcap(p_file_name) || '.txt';
return l_filename;
end GEN_FILENAME;
/
The function generates the following error if I use equals on a join, but is fine when I use a sub select for the function.
ORA-00604: error occurred at recursive SQL level 1
ORA-31011: XML parsing failed
ORA-19213: error occurred in XML processing at lines 1
LPX-00007: unexpected end-of-file encountered
00604. 00000 - "error occurred at recursive SQL level %s"
*Cause: An error occurred while processing a recursive SQL statement
(a statement applying to internal dictionary tables).
*Action: If the situation described in the next error on the stack
-- this query does not work
select dt.file_name,
GEN_FILENAME(dt.file_name) as file_name,
mf.file_path
from ( select 'Test' FOLDER,
'Test' AREA,
'File_Name' FILE_NAME,
systimestamp LAST_MODIFIED
from dual
) dt
left outer join (select 'Test/Test.File_Name.txt' file_path from dual) mf on mf.file_path = GEN_FILENAME(dt.file_name);
-- this query is working
select dt.file_name,
GEN_FILENAME(dt.file_name) as file_name,
mf.file_path
from ( select 'Test' FOLDER,
'Test' AREA,
'File_Name' FILE_NAME,
systimestamp LAST_MODIFIED
from dual
) dt
left outer join (select 'Test/Test.File_Name.txt' file_path from dual) mf on mf.file_path = (select GEN_FILENAME(dt.file_name) from dual);
I have seen other odd issues as well. I have asked them to gather statistics of the tables in the schema.
begin
for i in (select TABLE_NAME from USER_TABLES) loop
--Gather Table Statistics
sys.dbms_stats.gather_table_stats ( ownname => 'TEST', tabname => i.TABLE_NAME, cascade => true);
end loop;
end;
/
This resulted in the following error:
ORA-20000: Unable to analyze TABLE "TEST"."LOGMNR_SESSION_EVOLVE$", insufficient privileges or does not exist
ORA-06512: at "SYS.DBMS_STATS", line 40751
ORA-06512: at "SYS.DBMS_STATS", line 40024
ORA-06512: at "SYS.DBMS_STATS", line 40183
ORA-06512: at "SYS.DBMS_STATS", line 40732
ORA-06512: at line 5
ORA-06512: at line 5
I think this is all related, but I have never seen this type of issues before.
Any ideas?
Related
I am attempting to create a Oracle stored procedure which creates partitioned tables based off of a table containing the table names and the column to be partitioned with. A separate PL/SQL block iterates through the table and calls the procedure with the table name and the column name.
Procedure:
create or replace PROCEDURE exec_multiple_table_create (
table_name IN VARCHAR2,
column_name IN VARCHAR2
) IS
stmt VARCHAR2(5000);
tablename VARCHAR2(50);
columnname VARCHAR2(50);
BEGIN
tablename := table_name;
columnname := column_name;
-- DBMS_OUTPUT.PUT_LINE(tablename);
-- DBMS_OUTPUT.PUT_LINE(columnname);
stmt := 'create table '
|| TABLENAME
|| '_temp as (select * from '
|| COLUMNNAME
|| ' where 1=2)';
EXECUTE IMMEDIATE stmt
USING IN table_name, column_name;
stmt := 'alter table '
|| tablename
|| '_temp modify partition by range('
|| columnname
|| ')
(PARTITION observations_past VALUES LESS THAN (TO_DATE(''20000101'',''YYYYMMDD'')),
PARTITION observations_CY_2000 VALUES LESS THAN (TO_DATE(''20010101'',''YYYYMMDD'')),
PARTITION observations_CY_2001 VALUES LESS THAN (TO_DATE(''20020101'',''YYYYMMDD'')),
PARTITION observations_CY_2002 VALUES LESS THAN (TO_DATE(''20030101'',''YYYYMMDD'')),
PARTITION observations_CY_2003 VALUES LESS THAN (TO_DATE(''20040101'',''YYYYMMDD'')),
PARTITION observations_CY_2004 VALUES LESS THAN (TO_DATE(''20050101'',''YYYYMMDD'')),
PARTITION observations_CY_2005 VALUES LESS THAN (TO_DATE(''20060101'',''YYYYMMDD'')),
PARTITION observations_CY_2006 VALUES LESS THAN (TO_DATE(''20070101'',''YYYYMMDD'')),
PARTITION observations_CY_2007 VALUES LESS THAN (TO_DATE(''20080101'',''YYYYMMDD'')),
PARTITION observations_CY_2008 VALUES LESS THAN (TO_DATE(''20090101'',''YYYYMMDD'')),
PARTITION observations_CY_2009 VALUES LESS THAN (TO_DATE(''20100101'',''YYYYMMDD'')),
PARTITION observations_CY_2010 VALUES LESS THAN (TO_DATE(''20110101'',''YYYYMMDD'')),
PARTITION observations_FUTURE VALUES LESS THAN ( MAXVALUE ) )';
EXECUTE IMMEDIATE stmt
USING IN table_name, column_name;
RETURN;
END exec_multiple_table_create;
The PL/SQL block which is using the stored proc is:
BEGIN
FOR partition_item IN (
SELECT
table_name,
partition_column
FROM
partition_table
) LOOP
exec_multiple_table_create(partition_item.table_name, partition_item.partition_column);
END LOOP;
END;
Now, when I try executing the thing, this is what I am seeing:
Error report -
ORA-06550: line 9, column 9:
PLS-00905: object SCG_MYACCT_CUSTOMPC.EXEC_MULTIPLE_TABLE_CREATE is invalid
ORA-06550: line 9, column 9:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I have a feeling that I am missing something. Please let me know what it is. The table containing the reference data exists and contains data.
I have tried refreshing the table, rewriting and modifying the pl/sql block & the procedure code. Nothing seems to be working.
Thanks in advance.
UPDATE 1:
There was a glitch in the stored procedure where I needed to refer to the tablename rather than the columnname in the code above. However, I am getting a different error right now.
Error report -
ORA-06546: DDL statement is executed in an illegal context
ORA-06512: at "SCG_MYACCT_CUSTOMPC.EXEC_MULTIPLE_TABLE_CREATE", line 18
ORA-06512: at line 9
ORA-06512: at line 9
06546. 00000 - "DDL statement is executed in an illegal context"
*Cause: DDL statement is executed dynamically in illegal PL/SQL context.
- Dynamic OPEN cursor for a DDL in PL/SQL
- Bind variable's used in USING clause to EXECUTE IMMEDIATE a DDL
- Define variable's used in INTO clause to EXECUTE IMMEDIATE a DDL
*Action: Use EXECUTE IMMEDIATE without USING and INTO clauses to execute
the DDL statement.
Please help me out with this as well.
UPDATE 2:
I removed the USING part of the EXECUTE IMMEDIATE statement. That seemed to take care of the error I posted. Getting a different error with versions now:
Error starting at line : 1 in command -
BEGIN
FOR partition_item IN (
SELECT
table_name,
partition_column
FROM
partition_table
) LOOP
exec_multiple_table_create(partition_item.table_name, partition_item.partition_column);
END LOOP;
END;
Error report -
ORA-00406: COMPATIBLE parameter needs to be 12.2.0.0.0 or greater
ORA-00722: Feature "Conversion into partitioned table"
ORA-06512: at "SCG_MYACCT_CUSTOMPC.EXEC_MULTIPLE_TABLE_CREATE", line 37
ORA-06512: at line 9
ORA-06512: at line 9
00406. 00000 - "COMPATIBLE parameter needs to be %s or greater"
*Cause: The COMPATIBLE initialization parameter is not high
enough to allow the operation. Allowing the command would make
the database incompatible with the release specified by the
current COMPATIBLE parameter.
*Action: Shutdown and startup with a higher compatibility setting.
This issue is linked to another issue which I posted yesterday
oracle procedure to list table names and corresponding count
I am getting an XML error while querying the below query:
CREATE OR REPLACE VIEW V_CHECK_RECORDS_BUL AS
SELECT TABLE_NAME,
case
when S.TABLE_NAME_BUL in ('GD_MSTR_FLAT_CLAIM_POL','GD_MSTR_ERROR') then
TO_NUMBER(
EXTRACTVALUE( XMLTYPE(
DBMS_XMLGEN.GETXML('select count(*) c from ' || U.TABLE_NAME ||'where oe_name="BUL"')
), '/ROWSET/ROW/C'))
else
TO_NUMBER(
EXTRACTVALUE( XMLTYPE(
DBMS_XMLGEN.GETXML('select count(*) c from ' || U.TABLE_NAME)
), '/ROWSET/ROW/C'))
end as
NUM_ROWS
FROM USER_TABLES U JOIN GD_TABLE_ORDER S ON S.TABLE_NAME_BUL = U.TABLE_NAME order by S.order_id;
ERROR:
ORA-19202: Error occurred in XML processing
ORA-00933: SQL command not properly ended
ORA-06512: at "SYS.DBMS_XMLGEN", line 176
ORA-06512: at line 1
19202. 00000 - "Error occurred in XML processing%s"
*Cause: An error occurred when processing the XML function
*Action: Check the given error message and fix the appropriate problem
This error is occured when I use case statement to add a condition, otherwise it is working fine.
The view will be created, but during the selction of the view, this error is occuring.
The error is because you are missing a space in the inner query; but your quotes are also wrong; this:
U.TABLE_NAME ||'where oe_name="BUL"')
should be
U.TABLE_NAME ||' where oe_name=''BUL''')
----------------^
If you have a string literal that contains a single quote then you need to escape that with another single quote; two single quotes ('') are not the same as one double quote (").
Also, extractvalue is deprecated. You can do the same thing with xmlquery instead:
TO_NUMBER(
XMLQUERY(
'/ROWSET/ROW/C/text()'
PASSING XMLTYPE(
DBMS_XMLGEN.GETXML(
'select count(*) c from "' || U.TABLE_NAME || '" where oe_name=''BUL'''
)
)
RETURNING CONTENT
)
)
I tend to include double quotes around object names for this sort of thing just in case it ever has to deal with mixed-cased (quoted) identifiers.
So put together than becomes:
create or replace view v_check_records_bul as
select table_name,
case
when s.table_name_bul in ('GD_MSTR_FLAT_CLAIM_POL','GD_MSTR_ERROR') then
to_number(
xmlquery(
'/ROWSET/ROW/C/text()'
passing xmltype(
dbms_xmlgen.getxml(
'select count(*) c from "' || u.table_name || '" where oe_name=''BUL'''
)
)
returning content
)
)
else
to_number(
xmlquery(
'/ROWSET/ROW/C/text()'
passing xmltype(
dbms_xmlgen.getxml(
'select count(*) c from "' || u.table_name || '"'
)
)
returning content
)
)
end as num_rows
from user_tables u
join gd_table_order s on s.table_name_bul = u.table_name;
I've left out the order by clause as that really belongs as part of queries against the view, not as part of the view definition - though you would have to include it as a column in the view if you wanted to be able to use it for ordering later.
db<>fiddle demo
While attempting to manually execute the command below with user APPS (owner of WF_BPEL_QTAB queue) the error informed is occurring.
We did all the necessary research and the queue has no indexes (as some solutions suggest).
Command:
declare
l_purge_options dbms_aqadm.aq$_purge_options_t;
begin
l_purge_options.Block := False;
DBMS_AQADM.PURGE_QUEUE_TABLE(queue_table => 'APPS.WF_BPEL_QTAB'
,purge_condition => 'ENQ_TIME < trunc(sysdate) - 3
,purge_options => l_purge_options);
end;
Error:
ORA-00604: error occurred at recursive SQL level 1
ORA-01001: invalid cursor
ORA-06512: at "SYS.DBMS_AQ_INV", line 208
ORA-00918: column ambiguously defined
ORA-06512: at "SYS.DBMS_AQADM", line 1668
ORA-06512: at line 5
When using criteria from the queue table, you need to use the alias 'qtview'. Hence
declare
l_purge_options dbms_aqadm.aq$_purge_options_t;
begin
l_purge_options.Block := False;
DBMS_AQADM.PURGE_QUEUE_TABLE(queue_table => 'APPS.WF_BPEL_QTAB'
,purge_condition => 'qtview.ENQ_TIME < trunc(sysdate) - 3
,purge_options => l_purge_options);
end;
I have created a job_class having logging level as FULL.
SQL syntax for the same is :
BEGIN
dbms_scheduler.create_job_class(job_class_name => 'full_job_class',
comments => 'Job class having logging level as full.',
logging_level => dbms_scheduler.logging_full);
END;
Now I am trying to change attribute for all the listed JOB in my DB to set its job_class attribute to the newly created job_class.
SQL syntax for the same:
DECLARE
vs_statement VARCHAR2(100);
CURSOR c1 IS
SELECT '''' || owner || '.' || job_name || '''' as job_name
FROM dba_scheduler_jobs d
WHERE owner NOT IN ('SYS', 'DBSNMP', 'ORACLE_OCM', 'SYSTEM');
BEGIN
FOR rec IN c1 LOOP
execute immediate ('BEGIN dbms_scheduler.set_attribute(NAME => '||rec.job_name||', attribute => ''JOB_CLASS'', VALUE => ''FULL_JOB_CLASS''); END;');
END LOOP;
END;
But while running this code I am getting now and than below error:
ORA-27470: failed to re-enable "WEB"."REFRESH_PERFORMANCE" after making requested change
ORA-27476: "SYS"."FULL_JOB_CLASS" does not exist
ORA-06512: at "SYS.DBMS_ISCHED", line 4648
ORA-06512: at "SYS.DBMS_SCHEDULER", line 3052
ORA-06512: at line 1
But when I am executing one at a time to change job's attribute to set its job_class then I don't get any error.
Make sure you grant the EXECUTE object privilege as SYS to the schema attempting to make the change.
GRANT EXECUTE ON SYS.FULL_JOB_CLASS TO {JOB_OWNER};
I came accross interesting error where I am not sure about best way how to fix it. Given following block:
DECLARE
v_column_exists number := 0;
host_column_exists number := 0;
i number;
BEGIN
Select count(*) into v_column_exists from user_tab_cols where column_name = 'CONNECTIONDESCRIPTION' and table_name = 'NODES';
if (v_column_exists = 1) then
Select count(*) into host_column_exists from user_tab_cols where column_name = 'HOST' and table_name = 'NODES';
if (host_column_exists = 0) then
execute immediate 'alter table NODES add (Host varchar2(255))';
for item in (select connectiondescription, code from nodes) loop
... LOOP STUFF ...
end loop;
end if;
end if;
END;
I get following result:
PL/SQL: ORA-00904: "CONNECTIONDESCRIPTION": invalid identifier
ORA-06550: line 40, column 20: PL/SQL: SQL Statement ignored
ORA-06550: line 41, column 20: PLS-00364: loop index variable 'ITEM'
use is invalid
any ideas how to get rid of this error? Problem is occuring when column NODES.CONNECTIONDESCRIPTION is not present in database, however in such case for loop won't execute in runtime. I would need to disable these errors, but haven't found any way to do it. I have tried using ALTER SESSION SET PLSQL_WARNINGS='DISABLE:00904', but it had no effect.
Thanks
Correct approach was to use another dynamic query which bulk collects items to an array and then loop through this array.