Calling SQL*Plus commands in PL/SQL block - oracle

Is there any way to set the serveroutput on/off using pl/sql procedures/packages. I want to do some changes in displaying of my data on SQL*PLUS screen. like for my previous post

You cannot call SQL*Plus commands (which run only on the client) from PL/SQL (which runs only on the server).
In the particular case where you simply want to enable and disable message output, however, you can call the PL/SQL procedures dbms_output.disable and dbms_output.enable.
If you are depending on the data being written via dbms_output to be displayed to a human user, however, you are almost certainly doing something wrong. Production processes should be writing important data to some other location (i.e. a table somewhere), not writing to dbms_output and hoping that the client application happens to be configured to display the data.

Related

PL/SQL - retrieve output

Is there a way to retrieve output from PL/SQL continuously rather than wait until the SP completes its execution. Continuously mean as when it executes the execute immediate.
Any other mechanism to retrieve pl/sql output?
As per Oracle docs
Output that you create using PUT or PUT_LINE is buffered in the SGA. The output cannot be retrieved until the PL/SQL program unit from which it was buffered returns to its caller. So, for example, Enterprise Manager or SQL*Plus do not display DBMS_OUTPUT messages until the PL/SQL program completes.
As far as I know, there is a way, but not with DBMS_OUTPUT.PUT_LINE. Technique I use is:
create a log table which will accept values you'd normally display using DBMS_OUTPUT.PUT_LINE. Columns I use are
ID (a sequence, to be able to sort data)
Date (to know what happened when; might not be enough for sorting purposes because operations that take very short time to finish might have the same timestamp)
Message (a VARCHAR2 column, large enough to accept the whole information)
create a logging procedure which will be inserting values into that table. It should be an autonomous transaction so that you could COMMIT within (and be able to access data from other sessions), without affecting the main transaction
Doing so, you'd
start your PL/SQL procedure
call the logging procedure whenever appropriate (basically, where you'd put the DBMS_OUTPUT.PUT_LINE call)
in another session, periodically query the log table as select * from log_table order by ID desc
Additionally, you could write a simple Apex application with one report page which selects from the logging table and refreshes periodically (for example, every 10 seconds or so) and view the main PL/SQL procedure's execution.
The approach that Littlefoot has provided is what I normally use as well.
However, there is another approach that you can try for a specific use case. Let's say you have a long-running batch job (like a payroll process for example). You do not wish to be tied down in front of the screen monitoring the progress. But you want to know as soon as the processing of any of the rows of data hits an error so that you can take action or inform a relevant team. In this case, you could add code to send out emails with all the information from the database as soon as the processing of a row hits an error (or meets any condition you specify).
You can do this using the functions and procedures provided in the 'UTL_MAIL' package. UTL_MAIL Documentation from Oracle
For monitoring progress without the overhead of logging to tables and autonomous transactions. I use:
DBMS_APPLICATION.SET_CLIENT_INFO( TO_CHAR(SYSDATE, 'HH24:MI:SS') || ' On step A' );
and then monitor in v$session.client_infofor your session. It's all in memory and won't persist of course but it is a quick and easy ~zero cost way of posting progress.
Another option (Linux/UNIX) for centralised logging that is persistent and again avoids logging in the database more generally viewable that I like is interfacing to syslog and having Splunk or similar pick these up. If you have Splunk or similar then this makes the monitoring viewable without having to connect to the database query directly. See this post here for how to do this.
https://community.oracle.com/thread/2343125

Running SQL within same session as my SQLDeveloper debugger

This seems an obvious requirement/use-case to me, but I haven't found anything online.
I'm debugging a PL/SQL Stored Proc which stores data in pseudo-temporary tables along the way (they are just regular tables, whose content is wiped at the end of the transaction). I'd like to inspect these values as I go. However, there seems to be no way to run arbitrary SQL within the same session that is debugging the stored proc. If I try select * from temp_..., I get no rows back and I can see that I have more than one connection open to the database.
Is there a way to do this?
I doubt there is a way to do exactly what you asked. How about either a) committing the rows you're working with, querying them from another session during debug, then truncating your table when finished or b) add a default false debug parameter to your stored proc, then output what you wish when it is set true.
There is a setting in PL/SQL Developer, called Session Mode.
Go to Tools->Preferences->Connection->Session Mode, then select 'Single session'.
When you switch to single session mode your pl/sql procedure and other connections on behalf of one user will reside within single session. So you will be able to execute sql during debug and inspect all the data you want to.

Same stored procedure acts differently on two/(three) different IDEs

I just created a stored procedure in MS SQL DB using TOAD.
what it does is that it accepts an ID wherein some records are associated with, then it inserts those records to a table.
next part of the stored procedure is to use the ID input to search on the table where the items got inserted and then return it as the result set to the user just to confirm that the information got inserted.
IN TOAD, it does what is expected. It inserts date and returns information using just the stored procedure.
IN Oracle SQL developer however, it does the insert and it ends at that. It seems to not execute the 2nd part of the stored procedure which is a select stmt.
I just have a feeling that this is because of the jdbc adapter. Also why I'm asking is because I'm using a reporting tool Pentaho Report Designer and it would really make it easier if I can do 2 things at the same time. Pentaho Report Designer is also using jdbc adapters, not a coincidence maybe?
But if there are other things that I can tweak I'd really appreciate it.
This is a guess, but worth considering...
There are things called "Batches", where are sets of SQL Statements that are all sent to the server at once, and executed by the server as one set of statements, within a single server-side session. Sending a set of sql statements to the server as a batch will often result in different results than if you sent them one at a time, where each statement is executed in its own session.
I haven't used Toad (or Oracle) in a while, but as I recall, it dealt with batches differently than the other ide I used. If the second statement in your set is relying on being in the same session as the first, and in one ide it is in a separate session, then this might explain what is happening.

Display comments to user while executing Oracle procedure

Is it possible to display comments to user while executing a procedure in a package. My package has 3 procedures. I am calling each one after other. I want to display comments on console like procedure xyz is executing, procedure executed successfully. I added comments inside procedure like DBMS_OUTPUT.PUT_LINE('PROCEDURE EXECUTED SUCCESSFULLY') but didn't worked for me.
FYI i am using oracle 11g in windows 7 system.
You can't use DBMS_OUTPUT to display information on a procedure while it is running. This is because DBMS_OUTPUT.put_line doesn't display data on screen, rather, the data is put in a queue that is later read by the calling client (This queue is also invisible outside of its transaction). If you use SQL*Plus the queue is read and displayed automatically at the end of the procedure if you have SET SERVEROUTPUT ON.
Other means exist to follow the progress of a procedure while it is running:
You could write to a file instead. UTL_FILE.put_line will write directly if the parameter autoflush is set to true.
You could set session variables with DBMS_APPLICATION_INFO. These variables can be read with another session by querying v$session.
You could use AUTONOMOUS_TRANSACTIONS to log progress information in a dedicated table. This table can be queried by another session simultaneously.
As you can see you would need another process to read the information while it is written. In some applications, this would be achieved by running the main batch job in a new separate process, for example by calling DBMS_JOB or DBMS_SCHEDULER while the calling transaction loops on the progress table or file until the job is complete.
SQL*Plus is not an interactive client, you will need some more sophisticated environment to achieve this functionality.

in which part of stored procedures can set commands be used (declaration or executable)?

at which section we can write the set cmds(i.e like set pagesize 250) in oracle procedures
I see you have a similar question with an "oracle" tag and thought this general orientation might help.
SQL*Plus is a client program that provides an environment for issuing SQL commands to an Oracle database that also has some directives (the SET commands) that control the environment and formatting used for the duration of a session at the client. You may enter PL/SQL code in what are called "anonymous blocks", delimited by BEGIN/END, but this code is parsed at run time and never stored as a procedure in the database even though you are executing procedural code.
To blur the lines somewhat further, PL/SQL code (stored procedures/packages as well as anonymous blocks) may contain a calls to the DBMS_OUTPUT package that produces output, but this output is only visible if executing from a client environment that can receive the output. There are also size limitations to output that comes from DBMS_OUTPUT that can make its use problematic.
If you are trying to produce output from an Oracle database for reporting or post-processing you generally have these Oracle-based options:
If you have access to the database host file system you can use the Oracle UTL_FILE package to write directly to a file. You'll have to code the cursors, loops, and output formatting yourself in a PL/SQL procedure or anonymous block. Although the PL/SQL code will only write to the host filesystem, it can be called from any client.
If you need the output somewhere else and the output will fit within the DBMS_OUTPUT line and buffer limitations, you have the greatest formatting control if you write PL/SQL code that outputs exactly what you want and invoking this PL/SQL with the SQL*Plus SPOOL /SPOOL OFF directives to save the output on the client filesystem.
If your output doesn't fall into the above category (e.g. producing a 100 million row CSV file with 500 character wide lines), you might be able to get what you want by using the appropriate SQL functions in a query to get the results formatted as you need them and then using SQL*Plus SET directives to turn off everything (headings, page breaks, etc) that is not part of the result set (again using SPOOL /SPOOL OFF).
No where.
Those command are sqlplus specific -- never apply to pl/sql.
if you are using sqlplus, you can set them in sqlplus\admin\glogin.sql from within your oracle client install. this will get run whenever you open your sqlplus app. it would not be applied to a single procedure.

Resources