I am calling two different procedures of a same package from two different execution points in ORACLE APEX page. This Package has anonymous block in it. (Written at the end of package body)
Execution point: On Load: Before "Body" regions.
Calls : pkg_name.proc_1;
Item Read Only section.
Calls: pkg_name.proc_2;
I have put logging in the anonymous block in the package to check its execution. I observed that it is executing only once during page rendering.
But after the page rendering every time i make a call to the package (Through dynamic actions), the anonymous block gets executed.
I read, in oracle apex, every time a call is made to DB it will get a new DB connection from the pool.
How does the anonymous blocks execute in packages --> Once in a database session or Every time a package is called?
If Once in a database session, does that mean the entire page rendering happens in one database session unlike Dynamic actions?
Please help!
Thanks.
Yes. All rendering work is done together before the page is delivered to your browser - hence the single run of your package's anonymous block. But each PL/SQL dynamic action executes as a separate AJAX request, which means each one connects to the database and disconnects independently.
Related
What's the use of call dbms_scheduler.auto_purge()? The procedure is not listed in the official PL/SQL Packages and Types Reference.
When I execute this function, what will happen?
I've never used it. But, here's what Morgan's Library and Burleson Consulting say about it (didn't find any reference in "official" Oracle documentation).
AUTO_PURGE purges from the logs based on class and global log_history.
The AUTO_PURGE procedure uses the log_history values defined at the scheduler, job class and job log_history level to determine which logs should be purged. This procedure runs as part of the scheduled purge process, but it can also be run manually.
I am running DB queries in the UFT framework. During the execution, if the data is deleted in the backend tables, then UFT will throw the error message box as like below. I want to skip the error and continue and report the error description in the xml result sheet.
Error Message:
Run Error:
Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record
I am trying to add by recovery scenario by calling error function and proceed to next step. My error function is as like below:
Function RecoveryFunction1(Object, Method, Arguments, retVal)
If err.number<>"" then
error1=err.description
Reporter.reportevent micwarning,"Error ocurred:","","Error Details: "&error1&"
End If
End Function
I have added the above function in the function library and associated the recovery scenario in the test settings. But still error message is throwing up.
Please help me to handle the error message during run time instead of writing for each and every function 'on error resume next' statement.
You need to change the way you request the view of the database so that later modifications or deletions will not affect your query.
Take a look at the docs for the ADO Recordset. It specifies different cursor types, some of which will allow you to keep a static view of the data as it was when you ran the query, while others give live views. I'm not sure which one is best for your specific use case, so you should experiment and see which one works for you.
Failing that, you can try a move heavy-handed approach which is to begin a database transaction before you do your select, which should isolate your data processing from any external changes. However, that may be undesirable if your process takes a long time, as it may lock out other processes until you end your transaction and yield the locks on the rows you're looking at. Again, it depends on your specific database environment and the systems that interact with it.
i was trying to do a little splashscreen so my program could open querys withaout blocking my aplication.
The code i wrote is this.
procedure TOpenThread.OpenTable;
begin
FActiveTable.NonBlocking := true;
FActiveTable.open;
end;
procedure TOpenThread.AbrirTablas;
begin
FActiveTable := FOwnerPlan.TablasEdicion.Tabla;
Synchronize(OpenTable);
while FActiveTable.Executing do
begin
if Terminated then CancelExecution;
sleep(10);
end;
FActiveTable.NonBlocking := false;
end;
This code is executing in a thread, and keeps doing it while the main thread gets stucked
I'm using delphi 2007
This code is executing in a thread
Now, it does not. Your code is:
Synchronize(OpenTable);
This explicitly means OpenTable procedure is executed within Main VCL thread and outside of your background auxillary TOpenThread.
More details on Synchronize that you may try to learn from are at https://stackoverflow.com/a/44162039/976391
All in all, there is just no simple solutions to complex problems.
If you want to offload DB interactions into a separate thread, you would have to make that thread exclusive owner and user of all DB components starting from the very DB connection and up to every transaction and every query.
Then you would have to make means to ASYNCHRONOUSLY post data requests from Main VCL Thread to the DB helper thread, and ASYNCHRONOUSLY receive data packets from it. Something like OmniThreadLibrary does with data streams - read their tutorials to get a gist of internal program structure when using multithreading.
You may TRY to modify your application to the following rules of thumb.
It would not be the fastest multithreading, but maybe the easiest.
all database components work is exclusively done inside TOpenThread.Execute context and those components are local members variables to the TOpenThread class. The connection-disconnection made only within TOpenThread.Execute; TOpenThread.Execute waits for the commands from the main thread in the almost infinite (until the thread gets terminated) and throttled loop.
specific database requests are made as anonymous procedures and are added to some TThreadedQueue<T> public member of TOpenThread object. The loop inside .Execute tries to fetch the action from that queue and execute it, if any exists, or throttle (Yield()) if the queue was empty. Neither Synchronize nor Queue wrappers are allowed around database operations. Main VCL thread only posts the requests, but NEVER waits for them to be actually executed.
those anonymous procedures after being executed do pass the database results back into main thread. Like http://www.uweraabe.de/Blog/2011/01/30/synchronize-and-queue-with-parameters/ or like Sending data from TThread to main VCL Thread or by any other back-into-main-thread way.
TOpenThread.Execute only exits the loop if the Terminated flag is set and the queue is empty. If Terminated is set then immediate exit would loose the actions still waiting on queue unprocessed.
Seems boring and tedious but easy? Not at all, add there that you would have to intercept exceptions and process all the errors in the async way - and you would "loose any hope entering this realm".
PS. and last but not least, about "This code is executing in a thread, and keeps doing it while the main thread gets stucked" supposition, frankly, I guess that you are wrong here and i think that BOTH your threads are stuck by one another.
Without fully understanding how thread-to-thread locking is designed to work in this specific component, carpet-bombing code with calls to Synchronize and other inter-thread locking tools, you have quite a chance to just chase them all your threads into the state of mutual lock, deadlock. See http://stackoverflow.com/questions/34512/
I have a process flow built by someone prior which calls a very simple stored procedure. upon completion of the procedure the process flow has 2 transitions, one if the stored procedure was successful and the other if not. However, the stored procedure itself does not return anything that can be directly evaluated by the process flow like a return result. Now this procedure if it fails (with the ubiquitious max extants problem) it will call the branch which will call a stored procedure for sending a failure email message. If it succeeds the contrary will occur.
I had to tweak the procedure so I created a new one. now if it fails or succeeds the success branch is called regardless. I have checked all the docs from oracle as to how to make this work and for the life of me cannot determine how to make it work correctly. I first posted this on the oracle forum and got no responses. Does anyone have an idea how to make this work?
According to the Oracle Warehouse Builder guide:
When you add a transition to the canvas, by default, the transition has no condition applied to it.
Make sure that you have correctly defined a conditional transition as described in the Defining Transition Conditions section of the documentation.
A User Defined Activity will return an ERROR outcome if:
it raises an exception, or
it returns the value 3 and the Use Return as Status option is set to true
"However, the stored procedure itself does not return anything that
can be directly evaluated by the process flow like a return result."
This is the crux: if the operating procedure procedure produces no signal how can you tell whether it was successful? Indeed, what is the definition of success under this circumstance?
I don't understand why, when you had to "tweak the procedure", you wrote a new one instead of, er, tweaking the original procedure. The only way you're going to solve this is to get some feedback out of the original procedure.
At this point we run out of details. The direct option is to edit the original procedure so it passes back result info, probably through OUT parameters or else by introducing some logging capability. Alternatively, re-write it to raise an exception on failure. The indirection option is to write some queries to establish what the procedure achieved on a given run, and then figure out whether that constitutes success.
Personally, re-writing the original procedure seems the better option.
If this answer doesn't help you then you need to explain more about your scenario. What your procedure does, how you need to evaluate it, why you can't re-write it.
I am a newbie in Developer2000.
I have an Oracle pl/sql procedure (say, proc_submit_request) that fetches thousands of requests and submits them to dbms_job scheduler. The calling of dbms_job is
coded inside a loop for each request fetched.
Currently, i have a button (say, SUBMIT button) in oracle forms screen clicking which calls proc_submit_request.
The problem here is... the control does not return to my screen untill ALL of the requests fetched are submitted to the dbms_job (this takes hours to complete)
The screen grays out and just the hour-glass appears untill the completion of the procedure proc_submit_request.
proc_submit_appears returns a message to screen telling "XXXX requests submitted".
My requirement now is, once the user clicks the SUBMIT button, the screen should no longer gray out. The user should be able to navigate to other screens and not just struck with the submit screen untill the called procedure is completed.
I suggested running listeners (shell scripts and perl stuff) that can listen for any messages in pipe and run requests as back-ground process.
But the user is asking me to fix the issue in the application rather running listeners.
I've heard a little of OPEN_FORM built-in.
Suppose, I have two forms namely Form-1 and Form-2. Form-1 calls Form-2 using OPEN_FORM.
Now are the following things possible using OPEN_FORM?
On calling open_form('Form-2',OTHER-ARGUMENTS...), control must be in Form-1 (i.e. USer should not know that another form is getting opened) and Form-2 should call proc_submit_request.
User must be able to navigate to other screens in the application. But Form-2 must still be running until proc_submit_procedure is completed.
What happens if the user closes (exits) Form-1 ? Will Form-2 be still running?
Please provide me answers or suggest a good solution.
Good thought on the Form-1, Form-2 scenario - I'm not sure if that would work or not. But here is a much easier way without having to fumble around with coordinating forms being hidden and running stuff, and coming to the forefront when the function actually returns...etc, etc.
Rewrite your function that runs the database jobs to run as an AUTONOMOUS_TRANSACTION. Have a look at the compiler directive PRAGMA AUTONOMOUS_TRANSACTION for more details on that. You must use this within a database function/package/procedure - it is not valid with Forms (at least forms 10, not sure about 11).
You can then store the jobs result somewhere from your function (package variable, table, etc) and then use the built-in called CREATE_TIMER in conjunction with the form level trigger WHEN-TIMER-EXPIRED to go and check your storage location every 10 seconds or so - you can then display a message to the user about the jobs, and kill the timer using DELETE_TIMER.
You could create a single DBMS_JOB to call proc_submit_request. That way your form will only have to make one call; and the creation of all the other jobs will be done in a separate session.