dba_scheduler_job_run_details and dbms_output - oracle

dba_scheduler_job_run_details is capable to keep an dbms_output.put_line lines in dba_scheduler_job_run_details.output column. And it is so, when the job flows and exits normally. However, when I explicitly call dbms_scheduler.stop_job - all the output is missed.
How to avoid this behaviour?

I don't think you can avoid this, in the same way that if you killed off a SQL*PLus session that was running a procedure, you would not see the output either, because DBMS_OUTPUT simply puts data into an array and the calling environment is then responsible for retrieving that information and putting it somewhere (eg outputting to the terminal). You kill/stop the calling environment..and there's nothing left to go and get that output.
A better option would be to not utilise DBMS_OUTPUT solely as a debugging/instrumentation mechanism. Much better options exist in terms of capturing debugging information including viewing it from alternate sessions in real time etc.
Check out Logger at https://github.com/OraOpenSource/Logger. It is in common use by many in the Oracle community.

Related

PL/SQL local variables dump

Is it possible to get a string containing a list of the local variables names and their values at any point in time to aid in debugging (i.e. add to a row in the log table of the database as a text string)?
Is not possible to obtain a String with debug information, however using Sql Developer (Oracle free tool) you can DEBUG your pl/sql as usual likewise any other debug tool for another language including the VALUE for any variable.
This is taken from its documentation:
HTH
No, it is not possible.
DBMS_DEBUG can inspect PL/SQL variables, but it requires that the running session suspend and that a second session attach to it to perform the inspection.
I've thought about creating an API to spawn a second session (via DBMS_SCHEDULER) which would stop the calling session, inspect it, restart it, and report back.
That'd be very involved and I'm not sure it'd be a supported use case of DBMS_DEBUG.
Short of that, there is nothing.

how to print output in single line in oracle pl/sql

I have been using dbms_output.put_line to write the output in line, which is around 500000 lines with more than 500 characters.
I want the output in a single line and I had tried dbms_output.put . But it does not do so as dbms_output.put has a limitation of 32000 bits. Please suggest any solution.
DBMS_OUTPUT is a mechanism for displaying messages to standard output (i.e. a screen). The nature of PL/SQL programs is they tend to be batch oriented and frequently run as background jobs, so DBMS_OUTPUT has narrow applications. Writing out huge amounts of data is not one of them.
You haven't explained your use case, but the need to render millions of characters in a single stream of output, without carriage returns, suggests you want to write to a file. Oracle provides a built-in for this, UTL_FILE. We can iterate calls to UTL_FILE.PUT() to write as much data as we like to a single line in a file. Find out more.
UTL_FILE has one major constraint, which is it can only write to a file on the database server. Perhaps this is why you are trying to use DBMS_OUTPUT?
Something else? Oracle 12c supports Streaming in PLSQL via DBMS_XMLDOM. Check it out.
This is a pretty vague answer, because your question is pretty vague. If you edit your question and provide actual details regarding your issue I can make my response more concrete .

VB6 - Set Debug Mode via Registry?

I have a VB6 application that I'm trying to make log out differently. What I have is a flag in the registry (existing) which states if the application is set to Debug mode so that it would log out.
Within my code I then have lots of if statements checking if this is true. This means that there is a lot of processing time checking if a statement is true, which maybe not much really but as it does it so often it's an overhead I would like to reduce.
The code is full of statements like this
If isDebug = True Then
LogMessage("Log what is happening")
End If
So what I'm looking for is a better way to do this. I know I can set a debug mode within Project Properties -> Make, but this needs to be set prior to building the .exe and I want to be able to set this in production via the registry key.
Consider using a command line argument to set debug mode. I used to do this.
Dim sCommandLine() As String
sCommandLine = Split(Command$)
For I = 0 To UBound(sCommandLine)
' do something with each arg
Next I
You can also persist command line args inside the IDE, so you always have them when debugging. When running outside of the IDE, make a shortcut to the compiled application with the arguments in it.
I do something almost identical to what you have in mind in a lot of my code. Add this:
Sub LogDebug(ByVal strMsg As String)
If (isDebug) Then
LogMessage(strMsg)
End If
End Sub
Then just call LogDebug in your main program body, or call LogMessage directly if it's something you always want to log, regardless of the debug flag.
I'm assuming isDebug is a boolean here. If it's a function call, you should just create a global flag that you set at the beginning of the code, and check that instead of looking at the registry over and over. I don't think checking a boolean is that much of a processing load, is it?
You want to call a function if a runtime flag is set. The only thing I can see that could be faster is:
If isDebug Then
LogMessage("Log what is happening")
End If
But I doubt that either would be the cause of performance problems. Most logging frameworks promote code like that and even put the flag/log level as a parameter to the function. Just be sure that you don't have other places where you needlessly compute a log message outside of the conditional statement.
You might evaluate why you need logging and if the logs produced are effective for that purpose.
If you are looking for a problem that can be trapped using VB error handling, consider a good error handling library like HuntERR31. With it you can choose to log only errors instead of the debug message you are now doing. Even if you don't use the library, the docs have a very good description of error handling in VB.
Another answer still:
Read your registry flag into your app so that it's a session based thing (i.e. when you close and restart the app the flag will be checked again - there's no point in checking the registry with every single test).
Then (as per Tom's post) assign the value to a global variable and test that - far faster than a function.
To speed up logging you may want to consider dimensioning a string buffer in your app and, once it has reached a specific size, fire it into your log file. Obviously there are certain problems with this approach, namely the volatility of the memory, but if you want performance over disk access I would recommend such an approach.
This would, of course, be a lot easier if you could show us some code for your logging process etc.

Why would a stored procedure take forever to execute but the code in the procedure runs quickly on it's own?

Firstly, this is Oracle. If I do this...
execute my_package.sp_execute_my_procedure('...', '...');
It seems to run indefinitely (I let it go over night).
However, if I take the code from the stored procedure, slap it into a pl/sql anonymous block, put the declare keyword on my single cursor and run it, it finishes in like 10 minutes. Which is how long it should take.
Without posting all the code, at least right off the bat, has anyone ever seen anything like this?
UPDATE: Ok, so I'm noticing when I select from v$session, while running the proc I'm getting an "UNKNOWN" blocking_session_status with the event "direct path write temp."
I can't quite tell from the little bit of googling I've done so far what that means yet.
It is possible there is some kind of contention for the package object that is blocking your session before it can even run the code.
While the execute command is hanging, query V$SESSION to see what that session is waiting on.
Does your PL/SQL code use a bind variable, and your DECLARE block uses a literal in it's place? This can result in a different plan and therefore different performance.
However, if I take the code from the stored procedure, slap it into a pl/sql anonymous
block, put the declare keyword on my single cursor and run it, it finishes in like 10
minutes.
...
It basically has a big select, then for each row in the select it does a whole bunch of
insertions.
Did you include the inserts or not?

is there a way to track the values of certain variables after the end of a program in visual studio?

i have found myself several times in the need of knowing the last values set to a range of variables that were in a certain portion of code, or method; maybe dispersed around the program.
does anyone know a way to select variables and know the last value set to them after the program ends running - in a windows maybe ?
There isn't anything I know of that will record every value ever assigned to every variable in your program in case you want to look at it later. It is possible with VS2010's historical debugging abilities to look at "values from the past" although I haven't used this yet, so I don't know if that ability extends "beyond death" of the process.
You may also be able to use tracepoints (VS2008 and later). These are like breakpoints, but instead of stopping execution they simply print information to the debug output. So you could add a tracepoint for a variable so that each time it is changed its value is reported (basically the same as printing the values out in your code, but you don't have to change your code to enable them, and can add them while your code is executing).
Two simple approaches that will work for pretty much any dev environment are:
Write the values to an application log each time they change, then read the last reported entries. If you realise you need 5 values from all around the program, simply printing them to the debug output will only take a few seconds to add to your program. (If you can't do this easily, then you're not encapsulating your data very well).
Put a breakpoint on the destructor of the class you're interested in, or at the start of the shutdown process just before you destroy the objects, or the last line of code in your program (for statics) (etc) and just use the debugger to drill down into the data.

Resources