TLDR; Is there anything I can set in an Oracle Form that would let me bind a placeholder to a Data Block
's ORDER BY Clause
?
I'm developing a form using Oracle Form Builder 10.1.2.3.0 (because it's interfacing with a system that makes other form types undesirable).
It has a Data Block
with Query Data Source Type
= Table
.
Its WHERE Clause
allows the user to be flexible in the search, producing rows of varying interest. I want rows with a perfect match to appear before those that are not.
To implement this specification, I wrote the form's WHERE Clause
and ORDER BY Clause
to reflect this SQL*Plus example:
var sf varchar2(30)
exec :sf := 'X'
with mdual as (
select case when level=1 then dummy else dummy || level end dummy
from dual
connect by level <= 2
)
select *
from mdual
where :sf is null or dummy like '%' || upper(:sf) || '%'
order by case when :sf = dummy then 0 else 1 end asc, dummy;
The form variable reference is not as simple as :sf
and the WHERE Clause
is a bit more complicated as is the ORDER BY Clause
but this type of query is valid. When executed in SQL*Plus, it produces exactly the type of result I desire. You can reverse the first sort expression to prove it.
When I execute the form, I get an ORA-1008 until I comment the first ORDER BY
expression.
My conclusion is that Oracle Forms binds placeholder references in a WHERE Clause
but not an ORDER BY Clause
.
I could experiment with setting the Query Data Source Type
to Procedure
and pass the procedure the filter field but a view has more utility than a procedure and so I'd prefer to keep using the view that I've defined for the Query Data Source Type
.
Is there a way I can coerce Oracle Forms to do what I consider the right thing?
CodePudding user response:
You can use SET_BLOCK_PROPERTY
built-in function in order to make it dynamical and depending on a local or bind variable such as
DECLARE
v_orderby := ' CASE WHEN '||:sf||' = ''dummy'' THEN 0 ELSE 1 END, dummy';
BEGIN
SET_BLOCK_PROPERTY('block1',ORDER_BY, v_orderby);
EXECUTE_QUERY;
END;
which might be invoked from a trigger such as WHEN-NEW-BLOCK-INSTANCE
after sending cursor to this block by using another action such as clicking on a button or pressing a key such as enter etc.