Home » Developer & Programmer » Forms » Dynamically passing where condition
Dynamically passing where condition [message #514438] Mon, 04 July 2011 13:44 Go to next message
goparaju
Messages: 54
Registered: June 2011
Member
Hi Experts,

I am working on 6i reports.I have below scenario to achieve.

I have FIND window and MAIN Window.

FIND Window: contains EMPNO, ENAME,and FIND button.

MAIN WINDOW: EMPNO, ENAME, SAL, JOB

If i enter something in FIND window, by clicking FIND button, it will populate data in MAIN window.I have below query in WHEN BUTTON PRESSED TRIGGER.

declare
cursor c1 is select empno, ename, job, sal from emp
where empno=nvl(:FIND.empno,empno)
and ename=nvl(:FIND.ename,ename)

begin
--here i am populating data into MAIN window block
end;

It's working fine.

REQUIREMENT: i want to pass where statement dynamically.
Let us say if i pass only empno in FIND window, i want to pass 'WHERE empno=:FIND.empno' to existing select statement [I will keep select statement same without where condition]
If i pass empno and ename both, i want to pass 'WHERE empno=:FIND.empno and ename=:FIND.ename.

Could somebody help me how to pass where condition to existing select statement based on parameters we pass in FIND window.

Kindly help.

Thanks in advance.
Re: Dynamically passing where condition [message #514444 is a reply to message #514438] Mon, 04 July 2011 15:17 Go to previous messageGo to next message
Littlefoot
Messages: 21823
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
As far as I understood, you'd like to display the same result (records) in both form and report. Therefore, you'd like to pass form's WHERE clause to the report. If that's so, you could use GET_BLOCK_PROPERTY built-in and its LAST_QUERY property. Also, check SYSTEM.LAST_QUERY system variable.

Don't just "blindly" pass its value to the report - display it in the form, first, so that you'd see what it really contains. You might need to adjust it a little bit. Somewhere in the back of my mind there's the "255 characters limit" (i.e. if the WHERE clause is longer than that, you might need to split it to several pieces, pass all of them to the report, put them back together in the report and, finally, use it.

Anyway: once you manage to pass it successfully, the simplest way to use it in the report is a lexical parameter. If you didn't use it yet, check Reports Help - it's described in there. Also, search this board - I created an example or two previously.
Re: Dynamically passing where condition [message #514468 is a reply to message #514444] Tue, 05 July 2011 00:33 Go to previous messageGo to next message
goparaju
Messages: 54
Registered: June 2011
Member
Hi,

I mistyped it. Actually, I am working in form builder 6i.I want to pass where condition dynamically based on condition as i posted.

Kindly help me how to write the where condition and how to attach it exisiting condition.


Thanks in advance.
Re: Dynamically passing where condition [message #514475 is a reply to message #514468] Tue, 05 July 2011 01:11 Go to previous messageGo to next message
Littlefoot
Messages: 21823
Registered: June 2005
Location: Croatia, Europe
Senior Member
Account Moderator
You mistyped it, I misunderstood it.

It appears that you are filling the MAIN block manually (using a cursor loop you mentioned). Why is that so? It would be much easier if you kept it a data block and simply executed a query. There would be no need for "dynamic where conditions" or whatever - you'd just (in PRE-QUERY trigger) set
:main.empno := :find.empno;
:main.ename := :find:ename;
and that would be all.

Or, if you insist on some more typing, you'd set MAIN block's ONETIME_WHERE (or, possibly, DEFAULT_WHERE) property using SET_BLOCK_PROPERTY built-in.

What you are saying is that you'd want to create a WHERE condition dynamically and append it to cursor's SELECT statement. Well, as far as I can tell, that's not easy. In Reports, you'd use lexical parameter. I don't know what to use in Forms. From my point of view, "dynamically" here stands for "too complex" and, if I were you, I'd either leave it as it is (really, if it works OK, why fixing something that isn't broken?) or redesign a form so that it works as I explained at the beginning of this message.
Re: Dynamically passing where condition [message #514491 is a reply to message #514475] Tue, 05 July 2011 03:04 Go to previous messageGo to next message
goparaju
Messages: 54
Registered: June 2011
Member
Hi,

Thanks for your reply. My FIND window gets data from some other table, not from emp, and populates data into MAIN window EMP table block.

My problem is, i have 10 nvls in WHERE condition.If i don't pass parameters, the query is taking very long time because of NVL functions.For that, i thought of passing where condition dynamically,so that it will improve performance.

As per your suggestion, passing where condition dynamically is not advisable. Could you suggest me to improve the performance my query, instead of using NVL, can i use something else.

Below is my actually query which triggers when i press the FIND button in FIND window.

SELECT  ooha.order_number            
       ,ooha.cust_po_number
       ,oola.line_number
       ,we.wip_entity_name
FROM oe_order_headers_all ooha
    ,oe_order_lines_all oola
    ,mtl_system_items_b msib
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='ALLOY')a
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='GRADE')b
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='FORM') c
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='FINISH')d
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='TEMPER')e
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='DIM1')f
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='DIM2')g
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='DIM3')h
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='DIM4')i
    ,wip_reservations_v wrv
    ,wip_entities we
WHERE ooha.header_id=oola.header_id
AND   oola.ordered_item=msib.segment1
AND   msib.inventory_item_id=a.inventory_item_id
AND   a.inventory_item_id=b.inventory_item_id
AND   a.inventory_item_id=c.inventory_item_id
AND   a.inventory_item_id=d.inventory_item_id
AND   a.inventory_item_id=e.inventory_item_id  
AND   a.inventory_item_id=f.inventory_item_id
AND   a.inventory_item_id=g.inventory_item_id
AND   a.inventory_item_id=h.inventory_item_id
AND   a.inventory_item_id=i.inventory_item_id
AND   ooha.order_number=wrv.segment1  
AND   wrv.wip_entity_id=we.wip_entity_id
AND   a.element_name=NVL(:ALLOY,a.element_name)
AND   b.element_name=NVL(:GRADE,b.element_name)
AND   c.element_name=NVL(:FORM,c.element_name)
AND   d.element_name=NVL(:FINISH,d.element_name)
AND   e.element_name=NVL(:TEMPER,e.element_name)
AND   f.element_name=NVL(:DIM1,f.element_name)
AND   g.element_name=NVL(:DIM2,g.element_name)
AND   h.element_name=NVL(:DIM3,h.element_name)
AND   i.element_name=NVL(:DIM4,i.element_name)
GROUP BY ooha.order_number            
       ,ooha.cust_po_number
       ,oola.line_number
       ,we.wip_entity_name;


User may or may not pass parameters, if parameters are not passed, it will scan the entire table,query is taking long time.

Any other solution which acts like NVL and gives better performance.

Thanks.



CM: added [code] tags

[Updated on: Tue, 05 July 2011 03:46] by Moderator

Report message to a moderator

Re: Dynamically passing where condition [message #514499 is a reply to message #514491] Tue, 05 July 2011 03:38 Go to previous messageGo to next message
cookiemonster
Messages: 13959
Registered: September 2008
Location: Rainy Manchester
Senior Member
Michel gave an answer in your other post
Re: Dynamically passing where condition [message #514504 is a reply to message #514499] Tue, 05 July 2011 04:05 Go to previous messageGo to next message
cookiemonster
Messages: 13959
Registered: September 2008
Location: Rainy Manchester
Senior Member
Couple of points:
1) Can you please read and follow: How to use [code] tags and make your code easier to read?
2) Looking at the full query I would suggest your main problem is the data model - it's not third normal form. grade, finish, temper etc should all be columns in the same row. If they were it'd improve things immensely.
3) If you can't change the data model then you probably do need to do things dynamically, but you should change the from as well as the where.
So if the user hasn't entered a grade you should remove inline view b entirely from the query. Likewise for the others c to i.
Re: Dynamically passing where condition [message #514509 is a reply to message #514504] Tue, 05 July 2011 04:16 Go to previous messageGo to next message
cookiemonster
Messages: 13959
Registered: September 2008
Location: Rainy Manchester
Senior Member
Is that query even correct?
    ,(select inventory_item_id,element_name from mtl_descr_element_values where element_name='GRADE')b
.........
AND   b.element_name=NVL(:GRADE,b.element_name)

Only way that's going to find any records is if the user enters the value 'GRADE' in :grade or leaves it blank.
Likewise :form must be 'FORM' or blank, and so on.
Seems wrong to me. Think you're missing a column - element_value perhaps?
Re: Dynamically passing where condition [message #514757 is a reply to message #514438] Wed, 06 July 2011 05:47 Go to previous message
dude4084
Messages: 222
Registered: March 2005
Location: Mux
Senior Member
Hi here is a idea for you.

Your original query
select empno, ename, job, sal from emp 
where empno=nvl(:FIND.empno,empno)
and ename=nvl(:FIND.ename,ename)



Define a query string variable like this

query_string := 'select empno, ename, job, sal from emp 
where 1=1'


now check values of :Find.empno and :Find.ename (and more) as follow

if :FIND.empno is not null then
query_string  := query_string || ' and empno=:FIND.empno' 
end if;

if :FIND.ename is not null then
query_string  := query_string || ' and ename=:FIND.ename' 
end if;




Your SQL string is complete which you can check by
Message(query_string);
pause;



Now you can execute query_string by ???? method.


??? = research needed by me Sad

Good Luck

--Dude
Previous Topic: problem in running form on oracle developer suite 10g
Next Topic: clear block
Goto Forum:
  


Current Time: Thu Nov 28 15:53:21 CST 2024