Thanks for the solution. I have 2 questions:
1. If a SQL statement has multiple errors, then is there a chance that the invalid syntax check will be overridden by invalid table/column error.
Say I have this query: SELECT 1 FROM DUAL WHERE EMPNO IN (100, 200;
The above query has 2 errors:
i). EMPNO is not a valid column of DUAL
ii). The right parenthesis of IN clause is not closed.
When I execute the query "SELECT 1 FROM DUAL WHERE EMPNO IN (100, 200;", what error will I get:
Will I get "ORA-00907: missing right parenthesis" or will I always get "ORA-00904: "EMPNO": invalid identifier"
In other words, in which order the parsing is done?
Will it always first check for the syntax and then check for valid table names/column names?
If this is the case, I can safely use your suggested approach, since the tables will not exist in the schema while parsing.
2. Will the below implementation scale up if I apply the function against all rows of a large table. Any performance enhancement hint?
LiveSQL link:
https://livesql.oracle.com/apex/livesql/file/content_EL2HYLZDJROK64SOMELFG8ORC.html set serverout on
create or replace function fn_check_syntax(p_predicate varchar2)
return varchar2
is
l_status varchar2(20) DEFAULT 'VALID';
l_sql varchar2(4000);
begin
l_sql := 'SELECT 1 FROM DUAL WHERE '||p_predicate;
EXECUTE IMMEDIATE l_sql;
return l_status;
exception when others then
if SQLCODE in (-902, -904)
then
return 'VALID';
else
return SQLERRM;
end if;
end;
/
create table user_predicate (seq_num number, predicate varchar2(4000));
/
insert into user_predicate (seq_num, predicate) values (1, 'EMPNO in ( select mgr from emp) AND ( ( COMM is null or SAL > 100 )');
insert into user_predicate (seq_num, predicate) values (2, 'EMPNO in ( select mgr from emp)');
SELECT seq_num, fn_check_syntax(predicate) status from user_predicate;
February 23, 2017 - 2:32 am UTC
To my knowledge we do a validity check first (ie, is it possible that this query *could* be valid), then a semantic check (ie, can it be valid on *this* database).
In terms of performance, obviously each one will likely be a hard parse, so I wouldnt be keen on running tens of thousands of them.