Search records on block very slow oracle forms - oracle

I have procedure in which enter Visit Number and search records on block. But this procedure search records take some time 3 to 4 minutes and block have 12672 records. How to optimize procedure to search records fast.
CODE:
DECLARE
BEGIN
IF :CTRL_BLOCK.SRCH_VISITNO IS NULL THEN
MESSAGE('Please enter Visit No...');
GO_ITEM('SRCH_VISITNO');
ELSE
BEGIN
GO_BLOCK('cpvdtl');
FIRST_RECORD;
LOOP
IF :cpvdtl.visitno = :CTRL_BLOCK.srch_visitno THEN
exit;
ELSE
NEXT_RECORD;
END IF;
EXIT WHEN :SYSTEM.LAST_RECORD='TRUE';
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
MESSAGE('No Data found...!');
END;
END IF;
:CTRL_BLOCK.srch_visitno := null;
go_item('cpvdtl.visitno');
END;

Why reinventing the wheel?
Default Forms functionality works perfectly well, as simple as:
create a block on a table
run the form
enter query mode
enter search criteria into any column (wildcards included)
execute query
If any record matches criteria, it will be displayed on the screen.
If you insist on your own search field, create it (which is what you already did). Then:
I'd suggest you to create a push button
create a WHEN-BUTTON-PRESSED trigger which will
utilize SET_BLOCK_PROPERTY built-in, using the ONETIME_WHERE (or DEFAULT_WHERE; see which fits better) property, by setting the search field's value into the block's where clause
EXECUTE_QUERY
Why button and not only the search field? Because you'd then use WHEN-VALIDATE-ITEM trigger to SET_BLOCK_PROPERTY, but you couldn't EXECUTE_QUERY in that trigger as it is a restricted procedure. Yes, you could use KEY-NEXT-ITEM trigger, but - what if user navigates out of the search field using the mouse? That trigger wouldn't fire. I'd say that button is a simpler choice.

Related

How to highlight specific record using SET_BLOCK_PROPERTY

I have form in which when open form then all records shown on the block. User enter number on search option and specific record shown on the block. Now I want when search then all records remain on the block and highlight searched data.
BEGIN
SET_BLOCK_PROPERTY('block',default_where,'column= '||:block2.column);
GO_BLOCK ('block');
EXECUTE_QUERY;
END;
How to achieve this target in oracle forms 11g
Thanks
Please refer below link . This will solve your problem.
You need to create a visual attribute and need to assign at item_instance_property level.
http://www.orafaq.com/forum/t/171952/
Firstly, set Current Record Visual Attribute Group property of block to a spesific Visual Attribute which you'd like to highlight to the visited row of the block.
Then, provided the records are already queried and appears on the screen, a text field( :block2.column ) with a
WHEN-BUTTON-PRESSED trigger with the below code might be used to search among those records by entering the desired value and pressing enter :
go_block('block');
first_record;
while :block2.column != :block.column
loop
next_record;
end loop;

Update table using multi record block in post forms commit

what I wanted is to update my table using values from a multi record block and here is what I tried in post forms commit:
BEGIN
FIRST_RECORD;
LOOP
UPDATE table1
SET ord_no = :blk.new_val;
EXIT WHEN :SYSTEM.LAST_RECORD='TRUE';
NEXT_RECORD;
END LOOP;
END;
but when I save I got an error
FRM-40737: Illegal restricted procedure
FIRST-RECORD in POST-FORMS-COMMIT trigger.
OK, a few things to talk about here
1) I'm assuming that 'table1' is NOT the table on which the block is based. If the block was based on table1, simply as the user edits entries on screen, then when you do a COMMIT_FORM command (or the users clicks Save) then the appropriate updates will be done for you automatically. (That is the main use of a database-table based block).
2) So I'm assuming that 'table1' is something OTHER than the block based table. The next thing is that you probably need a WHERE clause on your update statement. I assume that you are updating a particular in table1 based on a particular value from the block? So it would be something like:
update table1
set ord_no = :blk.new_val
where keycol = :blk.some_key_val
3) You cannot perform certain navigation style operations when in the middle of a commit, hence the error. A workaround for this is to defer the operation until the completion of the navigation via a timer. So your code is something like:
Declare
l_timer timer;
Begin
l_timer := find_timer('DEFERRED_CHANGES');
if not id_null(l_timer) then
Delete_Timer(l_timer);
end if;
l_timer := Create_Timer('DEFERRED_CHANGES', 100, no_Repeat);
End;
That creates a timer that will fire once 100ms after your trigger completes (choose name, and time accordingly) and then you have your original code on a when-time-expired trigger.
But please - check out my point (1) first.

Oracle forms: Rollback an item to database value without changing form

Let's say if some condition is fullfilled, it shouldn't be possible to make any change to my entire block. I've found a simple way to do this:
In the 'WHEN-VALIDATE-ITEM' trigger on blocklevel, I've written this statement:
begin
if (-- custom statement --
and :system.record_status <> 'QUERY'
and get_item_property(:system.current_item,DATABASE_VALUE) <> name_in(:system.current_item)) then
msgbox('Can''t change');
copy(get_item_property(:system.current_item,DATABASE_VALUE), :system.current_item);
raise form_trigger_failure;
end if;
end;
The copy statement sets the item value back to database value. But the problem is, that the status of my form will go to 'CHANGED', while there actually is not really a change visible, since the item got rollbacked to the database value. So when I try to exit the form, the system asks me if I want to save my changes. And I don't want that to happen. How can I change this?
To avoid asking to User if want to save or not values, you can perform Key-Commit
BEGIN
EXECUTE_TRIGGER('KEY-COMMIT');
standard.commit;
END;

How to call a set focus on a form creation

I'm creating a small application with some 'Search' hotkeys, F1 to F4 to search into different tables of a database, so I've created a TPageControl to hold the search fields and also display the results, so I have 1 PageControl and 4 tab sheets, but I'm trying to put one if statement to set the focus on the proper search field and I'm calling it on the OnShow event of the TPageControl, but I'm getting a error message: Form:TForm cannot focus
If I didnt got it all wrong, it's because the text field cannot be found, considering I'm showing the page before the application can create the elements inside of this page, so, how can I edit this code or where can I use it to make it works, just remembering that I need to call this procedures with the hotkeys later on.
The procedure I'm using to set the focus is just a simple IF with 4 conditions in my real case:
procedure TForm.searchFocus; begin
if pgcSearches.TabIndex=0 then begin
editFieldNames.SetFocus;
end
else if pgcSearches.TabIndex=1 then begin
editFieldAdresses.SetFocus
end;
end;
A more 'explicit' help from another forum:
procedure TfrmMain.pcSearchesChange;
begin
case pcSearches.TabIndex of
0: ActiveControl:=edtSearchSongs;
1: ActiveControl:=edtSearchBibles;
2: ActiveControl:=edtSearchWarning;
end;
if Visible then
ActiveControl.SetFocus;
end;

Displaying recordset in oracle forms

I want to show result of cursor on form.
I have code:
(WHEN-MOUSE-CLICK)
DECLARE
job EMP.JOB%TYPE;
sal EMP.SAL%TYPE
CURSOR getJobs IS
SELECT job, sal FROM emp;
BEGIN
FOR rec IN getJobs
LOOP
-- append row to data grid or some element
END LOOP;
END;
Which element I can use to do this, or I have to use different method?
You don't have as such any grid control in Oracle Forms so instead you have to use a multi record data base block. The benefit is that you don't need to create the cursor and populate by looping through it. Instead forms is doing this for you if you set the block property correctly. In this simple case you only need to set the data source property to emp but if you have a where clause then then you specify that in the where clause property. Please check the Forms help for any further information about block properties. Finally to populate the block you need to move to the database block and the execute the query with Execute_Query builtin:
(WHEN-MOUSE-CLICK)
Go_Block(<NAME_OF_YOUR_BLOCK>);
Execute_Query;

Resources