I have a procedure that converts the result of a specific query in a CSV File which is saved in a directory in the server. My question is that is there any way that i can generate unique names for the file every time i save it?
try this
-- not tested
select to_char( sysdate,'yyyymmddhh24miss' ) || '.txt' File_nm from dual;
spool &File_nm ;
-- run query
spool off;
If you create a SEQUENCE, you can increment the sequence each time you go to write your file.
DECLARE
l_filename VARCHAR2 (200);
BEGIN
SELECT 'somename_' || seq_name.NEXTVAL INTO l_filename FROM DUAL;
END;
I want to store oracle output like table columns in a separate file and I need to check with columns based conditional statements.
I tried just execution of statements
I want to execute this PLSQL program
###############################
set serveroutput on declare v_sal number(10);
begin select sal into v_sal from emp where empno=7934;
if v_sal=1300 then update emp set sal=6666 where empno=7934;
end if;
end;
exit;
One more query
SQL> select name,OPEN_MODE from v$database;
NAME OPEN_MODE
--------- --------------------
TEST READ WRITE
I want to compare based on open_mode column when open_mode = READ WRITE, I want to execute one condition.
See the sample Timesten procedure below.
CREATE OR REPLACE PROCEDURE test_proc(employee_id IN NUMBER) AS
salary NUMBER;
BEGIN
SELECT emp_sal INTO salary FROM employee where emp_id = employee_id;
DBMS_OUTPUT.PUT_LINE('Employee Id:' || employee_id || ' Annual Income:' || salary*12);
END;
/
If I call the procedure from Command line interface(ttisql), dbms_output.put_line logs gets printed there only.
But I want to collect such debug logs to somewhere else in a log file. Whenever procedure get executed it should append these content to a file. Is there any possible way to do that?
If you are calling your procedure from ttisql as you've said you can use spool filepath and spool off to log any messages appeared on the screen. To append new information to the already existed log file just use APPEND option after filepath
spool c:\logfile.log append
I need to debug in pl/sql to figure times of procedures, I want to use:
SELECT systimestamp FROM dual INTO time_db;
DBMS_OUTPUT.PUT_LINE('time before procedure ' || time_db);
but I don't understand where the output goes to and how can I redirect it to a log file that will contain all the data I want to collect?
DBMS_OUTPUT is not the best tool to debug, since most environments don't use it natively. If you want to capture the output of DBMS_OUTPUT however, you would simply use the DBMS_OUTPUT.get_line procedure.
Here is a small example:
SQL> create directory tmp as '/tmp/';
Directory created
SQL> CREATE OR REPLACE PROCEDURE write_log AS
2 l_line VARCHAR2(255);
3 l_done NUMBER;
4 l_file utl_file.file_type;
5 BEGIN
6 l_file := utl_file.fopen('TMP', 'foo.log', 'A');
7 LOOP
8 EXIT WHEN l_done = 1;
9 dbms_output.get_line(l_line, l_done);
10 utl_file.put_line(l_file, l_line);
11 END LOOP;
12 utl_file.fflush(l_file);
13 utl_file.fclose(l_file);
14 END write_log;
15 /
Procedure created
SQL> BEGIN
2 dbms_output.enable(100000);
3 -- write something to DBMS_OUTPUT
4 dbms_output.put_line('this is a test');
5 -- write the content of the buffer to a file
6 write_log;
7 END;
8 /
PL/SQL procedure successfully completed
SQL> host cat /tmp/foo.log
this is a test
As an alternative to writing to a file, how about writing to a table? Instead of calling DBMS_OUTPUT.PUT_LINE you could call your own DEBUG.OUTPUT procedure something like:
procedure output (p_text varchar2) is
pragma autonomous_transaction;
begin
if g_debugging then
insert into debug_messages (username, datetime, text)
values (user, sysdate, p_text);
commit;
end if;
end;
The use of an autonomous transaction allows you to retain debug messages produced from transactions that get rolled back (e.g. after an exception is raised), as would happen if you were using a file.
The g_debugging boolean variable is a package variable that can be defaulted to false and set to true when debug output is required.
Of course, you need to manage that table so that it doesn't grow forever! One way would be a job that runs nightly/weekly and deletes any debug messages that are "old".
use
set serveroutput on;
for example:
set serveroutput on;
DECLARE
x NUMBER;
BEGIN
x := 72600;
dbms_output.put_line('The variable X = '); dbms_output.put_line(x);
END;
If you are just testing your PL/SQL in SQL Plus you can direct it to a file like this:
spool output.txt
set serveroutput on
begin
SELECT systimestamp FROM dual INTO time_db;
DBMS_OUTPUT.PUT_LINE('time before procedure ' || time_db);
end;
/
spool off
IDEs like Toad and SQL Developer can capture the output in other ways, but I'm not familiar with how.
In addition to Tony's answer, if you are looking to find out where your PL/SQL program is spending it's time, it is also worth checking out this part of the Oracle PL/SQL documentation.
Using UTL_FILE instead of DBMS_OUTPUT will redirect output to a file:
http://oreilly.com/catalog/oraclebip/chapter/ch06.html
As a side note, remember that all this output is generated in the server side.
Using DBMS_OUTPUT, the text is generated in the server while it executes your query and stored in a buffer. It is then redirected to your client app when the server finishes the query data retrieval. That is, you only get this info when the query ends.
With UTL_FILE all the information logged will be stored in a file in the server. When the execution finishes you will have to navigate to this file to get the information.
Hope this helps.
Its possible write a file directly to the DB server that hosts your database, and that will change all along with the execution of your PL/SQL program.
This uses the Oracle directory TMP_DIR; you have to declare it, and create the below procedure:
CREATE OR REPLACE PROCEDURE write_log(p_log varchar2)
-- file mode; thisrequires
--- CREATE OR REPLACE DIRECTORY TMP_DIR as '/directory/where/oracle/can/write/on/DB_server/';
AS
l_file utl_file.file_type;
BEGIN
l_file := utl_file.fopen('TMP_DIR', 'my_output.log', 'A');
utl_file.put_line(l_file, p_log);
utl_file.fflush(l_file);
utl_file.fclose(l_file);
END write_log;
/
Here is how to use it:
1) Launch this from your SQL*PLUS client:
BEGIN
write_log('this is a test');
for i in 1..100 loop
DBMS_LOCK.sleep(1);
write_log('iter=' || i);
end loop;
write_log('test complete');
END;
/
2) on the database server, open a shell and
tail -f -n500 /directory/where/oracle/can/write/on/DB_server/my_output.log
An old thread, but there is another alternative.
Since 9i you can use pipelined table function.
First, create a type as a table of varchar:
CREATE TYPE t_string_max IS TABLE OF VARCHAR2(32767);
Second, wrap your code in a pipelined function declaration:
CREATE FUNCTION fn_foo (bar VARCHAR2) -- your params
RETURN t_string_max PIPELINED IS
-- your vars
BEGIN
-- your code
END;
/
Replace all DBMS_OUTPUT.PUT_LINE for PIPE ROW.
Finally, call it like this:
SELECT * FROM TABLE(fn_foo('param'));
Hope it helps.
Try This:
SELECT systimestamp INTO time_db FROM dual ;
DBMS_OUTPUT.PUT_LINE('time before procedure ' || time_db);
I am using Oracle SQL (in SQLDeveloper, using the SQL Worksheet). I would like to print a statement before my select, such as
PRINT 'Querying Table1';
SELECT * from Table1;
What do I use to Print / show text output? It's not Print, because that gives me the error: Bind Variable Table1 is NOT DECLARED. DBMS_OUTPUT.PUT_LINE is an unknown command. (Obviously, I'm an inexperienced SQLDeveloper and Oracle user. There must be some synonym for Print, but I'm having trouble finding help on it without knowing what it is.)
for simple comments:
set serveroutput on format wrapped;
begin
DBMS_OUTPUT.put_line('simple comment');
end;
/
-- do something
begin
DBMS_OUTPUT.put_line('second simple comment');
end;
/
you should get:
anonymous block completed
simple comment
anonymous block completed
second simple comment
if you want to print out the results of variables, here's another example:
set serveroutput on format wrapped;
declare
a_comment VARCHAR2(200) :='first comment';
begin
DBMS_OUTPUT.put_line(a_comment);
end;
/
-- do something
declare
a_comment VARCHAR2(200) :='comment';
begin
DBMS_OUTPUT.put_line(a_comment || 2);
end;
your output should be:
anonymous block completed
first comment
anonymous block completed
comment2
PROMPT text to print
Note: must use
Run as Script (F5)
not
Run Statement (Ctl + Enter)
The main answer left out a step for new installs where one has to open up the dbms output window.
Then the script I used:
dbms_output.put_line('Start');
Another script:
set serveroutput on format wrapped;
begin
DBMS_OUTPUT.put_line('jabberwocky');
end;
You could set echo to on:
set echo on
REM Querying table
select * from dual;
In SQLDeveloper, hit F5 to run as a script.
You could put your text in a select statement such as...
SELECT 'Querying Table1' FROM dual;
For me, I could only get it to work with
set serveroutput on format word_wrapped;
The wraped and WRAPPED just threw errors: SQLPLUS command failed - not enough arguments
If I ommit begin - end it is error. So for me this is working (nothing else needed):
set serveroutput on;
begin
DBMS_OUTPUT.PUT_LINE('testing');
end;
If you don't want all of your SQL statements to be echoed, but you only want to see the easily identifiable results of your script, do it this way:
set echo on
REM MyFirstTable
set echo off
delete from MyFirstTable;
set echo on
REM MySecondTable
set echo off
delete from MySecondTable;
The output from the above example will look something like this:
-REM MyFirstTable
13 rows deleted.
-REM MySecondTable
27 rows deleted.