English 中文(简体)
Oracle PL/SQL - tips for immediate output / console printing
原标题:

I have a number of pl/sql procedures that can take several minutes to run. While developing them, I ve added a few print statements to help debug and also provide some feedback and progress indicators. Initially, I ran these on small test sets and output was almost instantaneous. Now that I m testing with larger test sets that take several minutes to run, I find that printing to the console is no longer suitable, because nothing gets printed until the procedure ends. I m used to working in environments that do not buffer their output and print it immediately and adding simple print-statements for simple debugging and diagnostic is common.

Is it possible in pl/sql to print output immediately (not buffered)? If not, what alternatives do people recommend to get a similar result?

最佳回答

You can have a procedure that writes messages to a table using an autonomous transaction something like:

procedure log (p_message)
is
    pragma autonomous_transaction;
begin
    insert into message_log (user, datetime, message)
    values (user, sysdate, p_message);
    commit;
end;

Then monitor the table from another Oracle session.

问题回答

we have a small trick for this.

you can use DBMS_APPLICATION_INFO.set_client_info(" some information here"); creating some variables and replace the string inside " ".

and use select client_info from v$session to monitor the progress.

I ve been using dbms_pipe for this purpose. Send messages to a named pipe and read them from another session. This method may not work in a RAC environment when the writing and reading processes may connect to a different node.

Alternatively you can insert messages into a table using a procedure that runs in its own session using "pragma autonomous_transaction". You can the query these messages from another session

Edit: I see that my second option has already been mentioned.

There are generally two options:

  • Send the output to an Oracle table (or temporary table)
  • Write to the (database host) filesystem with UTL_FILE

If you don t have OS access to the database host, you can still write to the dbhost filesystem and bind an Oracle externally-defined table to the file so it can be queried with a SELECT.

It may depend on your client tool. I haven t used SQL*Plus in a while, but when I m debugging procedures in PL/SQL Developer, I open a command window and issue a SET SERVEROUTPUT ON command. Then when I execute the procedure, anything printed by DBMS_OUTPUT.PUT_LINE shows up right away.

Edit: you re right, I guess I was only seeing that with larger amounts of output or something. Anyhow I did some searching online and came across this log4plsql - may be useful.

An alternative is to use a pipelined function that returns your logging information. See here for an example: http://berxblog.blogspot.com/2009/01/pipelined-function-vs-dbmsoutput.html When you use a pipelined function you don t have to use another SQLPLUS/Toad/sql developer etc... session.

You can use DBMS Pipe and the Pipe Viewer in PL/SQL Developer to asynchronously catch all infos as they are put into the pipe.

Be careful to only put things into a pipe when there s someone to read it. Otherwise, your call will fail when the pipe is full.

There s also the possibility of using events, PL/SQL Developer has an event monitor as well. And the docs should provide an example of how to do it.

Another option is to have your PL/SQL call a procedure to send an email with the log message in it. This requires that your database has email sending capability, which can be added using UTL_SMTP.





相关问题
Export tables from SQL Server to be imported to Oracle 10g

I m trying to export some tables from SQL Server 2005 and then create those tables and populate them in Oracle. I have about 10 tables, varying from 4 columns up to 25. I m not using any constraints/...

Connecting to Oracle 10g with ODBC from Excel VBA

The following code works. the connection opens fine but recordset.recordCount always returns -1 when there is data in the table. ANd If I try to call any methods/properties on recordset it crashes ...

How to make a one to one left outer join?

I was wondering, is there a way to make a kind of one to one left outer join: I need a join that matches say table A with table B, for each record on table A it must search for its pair on table B, ...

Insert if not exists Oracle

I need to be able to run an Oracle query which goes to insert a number of rows, but it also checks to see if a primary key exists and if it does, then it skips that insert. Something like: INSERT ALL ...

How can I store NULLs in NOT NULL field?

I just came across NULL values in NOT-NULL fields in our test database. How could they get there? I know that NOT-NULL constraints can be altered with NOVALIDATE clause, but that would change table s ...

Type reference scope

I m studying databases and am currently working on a object-relational DB project and I ve encountered a small problem with the number of possible constraints in an object table. I m using "Database ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

热门标签