Print DBMS_OUTPUT.PUT_LINE in a file with a bash script - sql

I have a pl/SQL query that has a variable .
I want DBMS_OUTPUT.PUT_LINE to a file used on the machine (linux)
Does someone know how to do this?

You need to put some pieces together. Here is my inspiration: DBMS_OUTPUT.PUT_LINE not printing
a) put your plsql in an sql script, e.g. d.sql - the key here is set serveroutput:
set serveroutput on size 30000;
begin
DBMS_OUTPUT.PUT_LINE('my line');
end;
/
exit
b) Then write another script - ksh this time - containing:
sqlplus / #d.sql > output.txt
If you want to restrain what displays from sqlplus, then read appropriate documentation about set statement

Related

How do I make a PL/SQL script output in two different ways depending on user input?

I am working on a PL/SQL script that will take a user decision to either display the results in the SQL Plus window, or export it to a .CSV file based on a user input:
ACCEPT output_location PROMPT 'Output: (S) -SQL Output to Screen (E) - Export to .CSV: '
!touch /my_path/My_output_file.csv
DECLARE
(list of variables);
CURSOR my_cursor IS ...;
BEGIN
IF '&output_location' = 'E' THEN
SPOOL $PWD/My_Output_File
OPEN my_cursor;
FETCH my_cursor into...;
WHILE (my_cursor%FOUND) LOOP
DBMS_OUTPUT.PUT_LINE(my output data);
FETCH my_cursor into...;
END LOOP;
CLOSE my_cursor;
SPOOL OFF
!cp $PWD/My_output_file.lst $PWD/My_output_file.csv
set define ">"
!/libreoffice/program/soffice.bin
set define "&"
ELSE IF '&output_location' = 'S' THEN
(Code to output cursor info as a normal SQL execution)
END IF;
END;
/
Everything between OPEN my_cursor and CLOSE my_cursor works if I move all of the spool and file opening commands outside of the BEGIN-END block. As it currently is, it gives me the error:
PLS-00181: unsupported preprocessor directive '$PWD'
I can move these commands and just have two distinct scripts for a user to run, but I would really prefer to have it all in a one stop shop. How do I split this one script into two different output modes?
This is kind of missmatch. You're mixing PL/SQL with bash commands.
!cp $PWD/My_output_file.lst $PWD/My_output_file.csv
set define ">"
!/libreoffice/program/soffice.bin
set define "&"
This is not valid PL/SQL and it won't work here. You have to either split your scripts or instead of using bash use utl_file package for creating and handling files.

Run several sql scripts and spool output in ubuntu

Im a teaching assistant for a databases course in my university. I have the assignments of all of the students. Each assignment has a file 'queries.sql'. Is there a way to run all these scripts at once and spool the output to its own output file in ubuntu?
you need look into SQLPLus documentation
see for SqlPlus command line parameters serveroutput and spool
2 exampleы of run sql files from sqplus
start.sql - the file that start student1.sql and student2.sql
student1.sql - file for student 1
student2.sql - file for student 2
to run the example you need run SqlPlus sqlplus myuser/mypassword#myserver #start.sql
the script files below
1 example start.sql spools each file into separate output
set serveroutput on
spool students1.out
##.\student1.sql
spool students2.out
##.\student2.sql
spool off
set serveroutput off
exit
2nd example start.sql spool all files into one output file
set serveroutput on
spool students.out
##.\student1.sql
##.\student2.sql
spool off
set serveroutput off
exit
students files - just simple "hello I'm student" scripts
student1.sql
begin
dbms_output.put_line('hello I`m student1');
end;
/
student1.sq2
begin
dbms_output.put_line('hello I`m student1');
end;
/

How to capture the result of stored procedure through shell script?

I'm trying to execute stored procedure through shell script and try to get return from stored procedure but I didn't get any thing from the stored procedure on other hand same thing I do with sqlplus prompt and I'm able to get the result
sqlplus -silent xxx#xxx <<EOF
set serveroutput on
declare
DE_REC_COUNT number(10);
begin
DE_DUP_PROC ('T_MCL_30404_20150317_020','MCL','30404','FT',DE_REC_COUNT);
end;
EOF
Through sqlplus prompt
SQL> set serveroutput on
declare
DE_REC_COUNT number;
begin
DE_DUP_PROC ('T_MCL_30404_20150317_020','MCL','30404','FT',DE_REC_COUNT);
end;
0
PL/SQL procedure successfully completed.
The version of the anonymous block in the shell script will not be executed as shown, because you don't have a slash after the block to run it. If you run that you get no output at all. If you change it to have a slash:
sqlplus -silent xxx#xxx <<EOF
set serveroutput on
declare
DE_REC_COUNT number(10);
begin
DE_DUP_PROC ('T_MCL_30404_20150317_020','MCL','30404','FT',DE_REC_COUNT);
end;
/
EOF
then you'll see:
0
PL/SQL procedure successfully completed.
You've shown the interactive version in SQL*Plus without the slash too, but you must have had that to see the output you showed.
If you want the zero - which seems to be coming from a dbms_output call in your procedure, rather than directly from your anonymous block - n a shell variable you can refer to later, you can assign the output of the heredoc to a variable:
MY_VAR=`sqlplus -silent xxx#xxx <<EOF
set serveroutput on
set feedback off
declare
DE_REC_COUNT number(10);
begin
DE_DUP_PROC ('T_MCL_30404_20150317_020','MCL','30404','FT',DE_REC_COUNT);
end;
/
EOF`
printf "Got back MY_VAR as %s\n" ${MY_VAR}
Note that I've added set feedback off so you don't see the PL/SQL procedure successfully completed line. Now when you run that you'll see:
Got back MY_VAR as 0
and you can do whatever you need to with ${MY_VAR}. It depends what you mean by 'capture' though.
Here's an example of how it can be done by surrounding the code with the evaluation operators (` back quotes):
#!/bin/sh
results=`sqlplus -s xxx#xxx <<EOF
set serveroutput on feedback off
declare
DE_REC_COUNT number(10);
begin
DE_DUP_PROC ('T_MCL_30404_20150317_020','MCL','30404','FT',DE_REC_COUNT);
end;
/
EOF`
echo $results
Lets say for instance I have a below procedure which calculates the sum of two numbers and prints the total using dbms_output.put_line() method
CREATE OR REPLACE
PROCEDURE SUM
(
a IN NUMBER,
b IN NUMBER)
AS
total NUMBER;
BEGIN
total:= a + b;
dbms_output.put_line(total);
END;
Then in order to call this in our shell script we need to call this procedure in an anonymous block and store in a variable, later using echo we can execute the command.
plsqlcode=`sqlplus -silent hr/sandeep#orcl <<EOF
set serveroutput on
begin
sum(10,20);
end;
/
EOF`
echo $plsqlcode
Ideally this is not a recommended approach you should keep your shell and pl/sql code in separate files.

Oracle how to print some message?

As we know in MSSQL we can write below line to print some message
print 'Some Message';
How we can do same in Oracle as print not working with Oracle?
Use
DBMS_OUTPUT.put_line('Some Message');
To expand on #mhasan's answer and #AlexPoole's comment: assuming that you're executing your script using SQL*Plus you'll need to add the beginning of your script before the first DECLARE or BEGIN:
SET SERVEROUTPUT ON SIZE 1000000
SET LINESIZE 255
If you're using a tool other than SQL*Plus to run your script there will be different ways to view output written to DBMS_OUTPUT. For example, in PL/SQL Developer a "Test" window has a "DBMS Output" tab where text written to DBMS_OUTPUT can be viewed after the test script terminates.
Share and enjoy.

How do we print characters line by line and save it to csv or text file in PLSQL

DECLARE
V_NUMBER NUMBER :=23;
BEGIN
LOOP
V_NUMBER:=V_NUMBER+1;
EXIT WHEN V_NUMBER:=25;
--Some kind of function to be applied for printing and nesting lines into CSV or TEXT file.
END LOOP;
COMMIT;
END;
Scripting an Oracle SQL Query for Creating a CSV or Text Typed File Output
Consider running this from a SQL Plus session and use the SPOOL command. All output of the SQL command that follows will be written to the file name you specify.
If you need to append your results each successive time the SQL commands are run, then an OS level command would work appropriately when invoking this sqlplus executable block of PL/SQL:
Where the file name of this script is: "sample_csv_out.sql"
DECLARE
v_total_columns constant number:= 3; -- Number of columns queried
v_column_counter number;
v_csv_record varchar2(1000);
c_csv_column_format constant varchar2(15):=
'<<COLUMN1_VAL>>,<<COLUMN2_VAL>>,<<COLUMN3_VAL>>';
cursor result_cur is
SELECT column1, column2, column3
FROM tablea
WHERE column1 = ... ;
BEGIN
v_csv_record:= 'COLUMN1,COLUMN2,COLUMN3';
dbms_output.put_line (v_csv_record);
FOR i in result_cur LOOP
v_csv_record:= replace(c_csv_column_format, '<<COLUMN1_VAL>>', i.column1);
v_csv_record:= replace(v_csv_record, '<<COLUMN2_VAL>>', i.column2);
v_csv_record:= replace(c_csv_record, '<<COLUMN3_VAL>>', i.column3);
dbms_output.put_line(v_csv_record);
END LOOP;
END;
So, for example in a WINDOWS O/S environment, the call to append the output to a specific file name would be:
C:\> sqlplus sample_csv_out.sql >> mycsv_out.csv
The >> notation instructs the operating system to pipe the output of running sample_csv_out.sql via a sqlplus session.
The command DBMS_OUTPUT does the rest. If you need more details, see more Oracle documentation on DBMS_OUTPUT.
COMMENTS: I chose the RECORD STRING TEMPLATE approach to make this script a little more flexible and reusable. I recommend to keep any data manipulation logic within the CURSOR statement. Often when the two are mixed, it gets harder to debug any typos in syntax within a long string of values.
The construction of an output record was also designed to reduce typos, mistakes and frustration... if there are more than 3 columns in your own scripts, adding another element to the output string is mostly a cut-and-paste operation. Likewise with the "header" row (column titles).
You can read and write files in PL/SQL using the UTIL_FILE package
http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/u_file.htm