Oracle DBMS_OUTPUT not returning anything if I call a specific procedure - oracle

I have a PL/SQL block I'm running that looks something like this
BEGIN
dbms_output.put_line('11');
schema.some_package.process_data(i);
dbms_output.put_line('22');
END;
When I run this block, the DBMS Output returns absolutely nothing. If I comment out the process_data procedure call, then it returns the 11, 22 as expected. The procedure is not raising any exceptions and appears to be processing correctly.
The process_data procedure does call many other procedures and too much code to share here, but does anyone have suggestions as to what I should be looking for that would be clearing ALL queued output, even output called after the procedure in my block?

The behaviour you describe would happen if something in your stack calls dbms_output.disable(). That suppresses all output until you call dbms_output.enable().
Re-enabling output doesn't recover the suppressed output because disable() purges the buffer as well as disabling subsequent calls to put_line(), get_line(), etc

Related

How to handle exception in oracle package?

I have a oracle package consisting of many procedures.
e.g.
pkg(
proc 1
proc 2
proc 3
);
while executing the package proc 1 gets called first and within proc 1,proc 2 is called.
SO what if i face an exception in proc 2 then i want to rollback all the DML's done in proc 1.
You don't have to do anything, Oracle will perform rollback for you. Just don't commit anywhere within those procedures - let the caller decide whether to commit or not, after everything is done.
Also, don't DDL as it'll implicitly commit everything that has been done so far.
Adding to what Littlefoot mentioned, please please have in consideration whatever IDE you are working with. There are some settings of auto-commit that I recommend to you that should be turn off. Otherwise, rollbacks won't help.

unix sqlplus call doesnt return control sometimes

I am facing one issue, which I am trying to fix for sometime.
I have a shell script, which calls a pl/sql stored procedure using sqlplus. Most of the time it runs fine, but the script becomes idle(S) waiting for the procedure to be completed. When I investigated, the procedure has been completed successfully at oracle end, and the session is also complete, but the control has not been given back to sqlplus/shell script, which is why it is waiting. Can someone guide me how to crack this issue.
RESULT=`sqlplus user/pwd#ip/servicename <<EOF
SET SERVEROUTPUT ON;
spool out.log;
CALL schmea.package.proc
quit;
EOF`;
Add a blank line after "QUIT".
And, this is unrelated but remove the semicolon after SQLPlus commands (set serverutput, quit, spool)

Oracle PL/SQL: How to detect if a procedure is ALREADY running?

Please suppose that we have a procedure inside a package:
MY_PACKAGE.MY_PROCEDURE
This procedure could be launched from many users.
How can I modify the procedure in order to detect if the procedure is at present running since launched from another user?
What is the safest way to detect it?
Thank you for considering my request.
EDIT 01: "It'll depend on why you need to know if a proc is already running or not" ==> If the procedure is at present running, it WON'T be launched again.
You can use the DBMS_APPLICATION_INFO package for such information.
PROCEDURE MY_PROCEDURE(..) IS
BEGIN
DBMS_APPLICATION_INFO.SET_CLIENT_INFO('MY_PACKAGE.MY_PROCEDURE running');
... All your stuff
DBMS_APPLICATION_INFO.SET_CLIENT_INFO(NULL);
EXCEPTION
WHEN OTHERS THEN
DBMS_APPLICATION_INFO.SET_CLIENT_INFO(NULL);
RAISE;
END MY_PROCEDURE;
In order to check it, you can select V$SESSION View:
SELECT *
FROM v$session
WHERE client_info = 'MY_PACKAGE.MY_PROCEDURE running';
If you get any records then the procedure is running.
Based on what others have mentioned and a quick perusal of the DBMS_LOCK package header it appears that you can use the various DBMS_LOCK routines to accomplish what you're trying to do. If I'm reading the header comments correctly you'd want to call ALLOCATE_UNIQUE to get a handle to a unique, named lock, then you'd call REQUEST with the locking mode set to 'x' (Exclusive) to try to grab the lock. If the REQUEST call returns 0 you can go ahead and run your routine. When done, call RELEASE to make the lock available to the next caller.
Best of luck.

PL/SQL exception handling: do nothing (ignore exception)

This is a question I am asked very frequently. Since I couldn't find any exact duplicate on stackoverflow, I thought I'd post it as a reference.
Question:
In PL/SQL, I know how to catch exceptions and execute code when they are caught, and how to propagate them to the calling block.
For example, in the following procedure, the NO_DATA_FOUND exception is handled directly, while all other exceptions are raised to the calling block:
CREATE OR REPLACE PROCEDURE MY_PROCEDURE()
IS
BEGIN
do_stuff();
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Do something
handle_exception();
WHEN OTHERS THEN
-- Propagate exception
RAISE;
END;
But what command should I use to ignore one or all raised exceptions and return execution control back to the calling block?
While I agree that 99% of the time it is bad practice to silently ignore exceptions without at least logging them somewhere, there are specific situations where this is perfectly acceptable.
In these situations, NULL is your friend:
[...]
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
Two typical situations where ignoring exceptions might be desirable are:
1) Your code contains a statement which you know will fail occasionally and you don't want this fact to interrupt your program flow.
In this case, you should enclose you statement in a nested block, as the following example shows:
CREATE OR REPLACE PROCEDURE MY_PROCEDURE()
IS
l_empoyee_name EMPLOYEES.EMPLOYEE_NAME%TYPE;
BEGIN
-- Catch potential NO_DATA_FOUND exception and continue
BEGIN
SELECT EMPLOYEE_NAME
INTO l_empoyee_name
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 12345;
EXCEPTION
WHEN NO_DATA_FOUND THEN
NULL;
WHEN OTHERS THEN
RAISE;
END;
do_stuff();
EXCEPTION
WHEN OTHERS THEN
-- Propagate exception
RAISE;
END;
Note that PL/SQL generally does not allow for the On Error Resume Next type of exception handling known from Visual Basic, where all exceptions are ignored and the program continues to run as if nothing happened (see On error resume next type of error handling in PL/SQL oracle). You need to explicitly enclose potentially failing statements in a nested block.
2) Your procedure is so unimportant that ignoring all exceptions it throws will not affect your main program logic. (However, this is very rarely the case and can often result in a debugging nightmare in the long run)
BEGIN
do_stuff();
EXCEPTION
WHEN OTHERS THEN
-- Ignore all exceptions and return control to calling block
NULL;
END;
Another scenario when it does make sense to silently ignore exception:
When you call a script that is expected to create an object if it does not exist, and you do not have a create-or-replace syntax for that object.
PLSQL objects have a create-or-replace syntax, but tables and indexes do not.
Then we can put such scripts in a block and ignore the raised exception.

Secure code block execution in Oracle

For example I have a code:
BEGIN
BEGIN
-- First Part
call_1_1();
call_1_2();
...
call_1_N();
END;
BEGIN
-- Second Part
call_2_1();
call_2_2();
...
call_2_M();
END;
END;
This code placed at package and running in a job. Execution of this code (job) can be stopped from the outside by stopping the job. Interrupting could crach execution in the middle of the each block. And the question is how secure the execution of the blocks First Part or Second Part when someone interrupting execution from the outside.
Either all the transaction will complete or none of the transaction will complete. Guaranteed. You have to manage your transactions. For example don't commit before the end of the "block" if you want the block to be in one transaction.

Resources