Before I ask my question, I have to say that the database that I'm working on doesn't have foreign keys, so I can't make master-detail blocks, and because of that I'm using workaround with go_block, clear_block, execute_query and triggers.
I have a form with two blocks. If we presume that the both blocks are filled with info, and that I want to execute query on first one, is there a way to clear the other block before entering query mode?
e.g.
Block1: ID, NAME, SURNAME
Block2: INFO1, INFO2, ..., Id_block1 etc.
So, if there is info on both blocks, and I enter the query mode on Block1, whole block clears so I can enter search criteria, but the second block still has the data from the last executed query. Is there a way to clear the data on the second block as well? Once again, I want to clear the data from Block2 when I'm IN ENTER-QUERY MODE on Block1.
Workflow: Enter-query mode Block1, execute-query Block1, NEW-RECORD-INSTANCE trigger activates (where workflow continues), go_block('Block2'), execute_query on Block2 (with where clause Id_block1 = block1.id).
I'm using Oracle Forms 10g. I appreciate any help you can provide.
It is possible to create the MASTER-DETAIL relationship while creating one of the blocks in your form
or
you can just write the following on the KEY-ENTQRY trigger :
go_block('block2');
clear_block;
go_block('block1');
enter_query;
After this, the block1 will be in the enter-query mode and you can search the data and just execute the block.
Related
I have an APEX 5.0.3.00.03 page with dozens of criteria fields, followed by a region containing an Interactive Report (IR). I want to defer the IR being produced until a "Generate" button is clicked, but I am having troubles. The report without criteria would generate millions of rows, via a nasty 5 table join, so I want to defer it processing until the user is ready. I know that I can do a /*+ FIRST_ROWS */ hint, but still want to avoid invoking the SQL until the user picks some criteria.
I tried the following:
Created a Hidden Field P210_WAIT, initial value of 'TRUE', which I included in the SQL criteria like this:
select * from tab_1, tab_2, tab_3, tab_4, tab_5
where :P210_WAIT != 'TRUE'
and -- join, and dozens of other criteria here
and in a dynamic action on the Generate button, I do two things:
Execupte PL/SQL Code to set :P210_WAIT := 'FALSE';
Refresh Action:
Action: Refresh
Affected elements: Selection Type: Region. Region: (region containing my IR)
I have debug statements in the PL/SQL code, and they are appearing, but the SQL to produce the report is not being run, implying that the Refresh Action is not "waking up" the IR.
It does appear the IR SQL is being executed on page load, as I was dynamically setting the IR Attribute "When No Data Found" value to initially say "Please select criteria and click the Generate button to display report" and that was working.
If I understand your problem correctly, your main problem here would be: the dyanamic action to refresh the region is not working, am i correct?
If that is the problem, try this:
First, make sure that all the bind variables in the source query is listed on the Page Items to Submit under the source query region.
Then, Assign Static ID for the IR region.
Next will be, changing the Refresh dynamic action to Execute Javascript and paste this
$('#static_id').trigger('apexrefresh');
Hope this helps.
I want add to my block text item where I display count of my all record:
code is:
BEGIN
GO_ITEM('KIEKKAT');
SELECT COUNT(*)
INTO :KATEGORIJA.KIEKKAT
FROM KATEGORIJA;
END;
This wordk only if I choose trigger "WHEN-MOUSE-CLICK" ,but then all other items not display data. If I choose other trigger all items not displaying anything. i want tat this text item will all time display count of record. Please say me, how to do it, whicj trigger set I do my code if correct ?
I would consider a Summary item for this purpose - especially if you already have a block based on the KATEGORIJA table.
You add an item which is based on a COUNT from that block: set Calculation Mode to Summary, Summary Function to Count, and set Summarized Block to the block. Set the Query All Records property on the block to True.
Try it on the POST-SELECT trigger at the block level.
From the documentation:
Description
The Post-Select trigger fires after the default selection phase of query processing, or after the successful execution of the On-Select trigger. It fires before any records are actually retrieved through fetch processing.
Usage Note:
Use the Post-Select trigger to perform an action based on the outcome of the Select phase of query processing such as an action based on the number of records that match the query criteria.
Edit.
take a look at this
https://forums.oracle.com/forums/thread.jspa?threadID=883340
You can get the number from a block property.
I have a report that is listing students and I want a column to edit a student. I've done so by following this answer:
How do you add an edit button to each row in a report in Oracle APEX?
However, I can only seem to pass 3 items and there's no option to add more. I took a screenshot to explain more:
I need to pass 8 values, how can I do that?
Thanks!
Normally, for this you would only pass the Primary Key columns (here looks like #RECORD_NUMBER# only). The page that you send the person to would then load the form based on the primary key lookup only. If multiple users were using this application, you would want the edit form to always retrieve the current values of the database, not what happened to be on the screen when a particular person ran a certain report.
Change the Target type to URL.
Apex will format what to already have into a URL text field which magically appears between Tem3 and Page Checksum.
All you need to do is to add your new items and values in the appropriate places in the URL.
I found a workaround, at least it was useful to my scenario.
I have an IR page, query returns 4 columns, lets say: ID, DESCRIPTION, SOME_NUMBER,SOME_NUMBER2.
ID NUMBER(9), DESCRIPTION VARCHAR2(30), SOME_NUMBER NUMBER(1), SOME_NUMBER2 NUMBER(3).
What I did was, to setup items this way:
P11_ITEM1-->#ID#
P11_ITEM2-->#DESCRIPTION#
P11_ITEM3-->#SOME_NUMBER##SOME_NUMBER2#
Previous data have been sent to page 11.
In page 11, all items are display only items.
And P11_ITEM3 actually received two concatenated values.
For example, the calling page has columns SOME_NUMER=4 and SOME_NUMBER2=150
so, in pag1 11, P11_ITEM3 shows 4150
In page 11 I created a Before Footer process (pl/sql expression)
to set up new items, for example P11_N1 as source SUBSTR(P11_ITEM3,1,1)
and item P11_N2 as source SUBSTR(P11_ITEM3,2,3)
So, I had those items with corresponding values from the calling IR page.
The reason I did not pass the primary key only for new lookup access, is because i do not want to stress database performing new queries since all data are already loaded into page items. I've been an oracle DBA for twenty years and I know there is no need to re execute queries if you already have the information somewhere else.
These workarounds are not very useful for a product that bills itself as a RAD tool.
Just include a single quoted word in the select statement (Select col1, 'Randomword', col2 from table 1;)
Then define that column as a link and bingo! More items than 3 to select.
I am using ASP/VB Script in my project but, i don't have much idea of Pagination in Classic ASP. I have designed a datagrid format using tables and looping. That table is filled by accessing database. As we have a huge amount of data to display, we need pagination.
Thanks in advance
The pagination problem is not inherently to ASP classic or VBScript. You need first to define which strategy to follow:
In the client:
Ajax style pagination (You can use a jQuery plugin like SlickGrid)
Linked pagination: Your page have links to page 1, page 2, etc.
Infite scrolling: This is a modern way to do pagination, with more results added to the page via ajax
In the server
Full DB results retrieve and return only the page asked. This is sometimes necessary.
Full DB retrieve but caching the result so subsequent page request come from the cache, not the DB
Ask the DB only the page asked (Different techniques depending on the DB engine)
There is a issue you need to be aware of... the built-in ASP record set will allow pagiing, however is not very efficient. The entire result set gets returned to the browser and then it locates the appropriate page and displays that data.
Think of it like this... your result set is a 4 shelf book case. When you ask for page one all 4 shelves of books get returned. The the display code says "Okay now only show page 1". If you then ask for page two... All four shelves of books gets returned and then the display code says "Okay give me page 4".
So, you should look for a paging solution that takes place on the server, inside the database. This way if you ask for page 15 of a 50 page result, the database will only return one shelf of books.
This google query should put you on the right track.
Edit: How SQL Paging Works
You must us a stored procedure
One of the input parameters is the page to view
The stored procedure filters the results on the server
Here is the basic concept of what happens inside the proc:
Step 1:
Create a temp table that stores the entire result set. My preference is to store only two values in this temp table. An identity seed value called RowId and the primary key of the result data. (I'm one of those people that believes in non-sensical identity seed keys)
Step 2:
Insert all the PKey values from the select statement into the temp table
Step 3:
Determine the StartRowId and EndRowId based on the input page parameter.
Step 4:
Select from the temp table using an inner join to the datatable on the PKey. In the where clause limit the result so the RowId (of the temp table) is between StartRowId and EndRowId. Make sure to Order By the RowId.
Set page size
recordset.PageSize = 100 ' number of records per page
Set the current page
recordset.AbsolutePage = nPage ' nPage being the page you want to jump to.
Other useful bits:
recordset.RecordCount ' number of records returned
recordset.PageCount ' number of pages based on PageSize and RecordCount
That's the basic info. You'll still need to loop through the appropriate number of records, and check the page number as it is passed back to the page.
I have a block based on a table. If I enter "12345" in enter query mode, it creates a query with
WHERE my_field = '12345'
If I enter "12345A", it goes
WHERE (upper(my_field) = '12345A' AND my_field like '12%')
which is bad, because my_field is indexed normally (not on upper(my_field)). I have tried toggling "Case restriction" attribute between mixed and upper, and "Case insensitive query" between yes and no, nothing seems to help. I also have a block level PRE-QUERY trigger (trigger starts with a RETURN; statement) set on override, so nothing should mess with the formation of the query, yet it still messes up.
Any ideas on what else I could try?
EDIT:
There was an obscure function call within WHEN_NEW_FORM_INSTANCE trigger to some attached library that reset all trigger block's items to CASE_SENSITIVE_QUERY = TRUE. Never would have guessed.
Not sure how the query is getting changed to that form;
WHERE (upper(my_field) = '12345A' AND my_field like '12%'
First check that there are no enter query or prequery triggers in the form. Somebody might have attached a trigger at a higher level. Oracle is not that smart to rewrite the query.Check that you are tying to a table not a view or stored procedure,...
If all else fails, enable the query triggers in the data black and rewrite the where clause yourself. It is pretty straightforward.
Give version of oracle forms before you post.
The
my_field like '12%'
Uses the index. The subset is then filtered with
upper(my_field) = '12345A'
So it might not be as bad as you think....
The most naive question, Can you update the column so it's all uppercase? I mean would it cause some inconvenience to your app?
If you can, it could be handled with a database trigger to ensure it's allways uppercase.
If you can't, then I suggest you create another field that you keep updated to uppercase with a database trigger.
You can also create a function index so it's upper(my_field).