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

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

Related

Oracle SQLPlus: Echo without line numbers?

I'm working on a solution where several SQL and PL/SQL scripts are being run together, in a batch of sorts, via SQL*Plus.
I'm declaring SET ECHO OFF; and SET ECHO ON; at relevant points in the scripts so as to output relevant code.
Currently the output looks something like this:
SQL> DECLARE
2 ct number := 0;
3 ctChanges number := 0;
4
5 BEGIN
6 select count(*) into ct from ...
7 (...rest of code block...)
"some specific status message"
Commit executed.
We keep this output as a run-log in our build-environment, but can also access it as a plain text file.
One downside of this format however, is that if I'd like to copy a certain section of the code and run it again in an IDE (like Toad or SQL Developer), it's hard to exclude the line numbers.
Is it possible to tell SQL*Plus to output the code as above, but without including the line numbers?
You can use options sqlnumber and sqlprompt:
set sqlprompt ''
set sqlnumber off
SET SQLN[UMBER] {ON|OFF}
SET SQLNUMBER is not supported in iSQL*Plus
Sets the prompt for the second and subsequent lines of a SQL command or PL/SQL block. ON sets the prompt to be the line number. OFF sets the prompt to the value of SQLPROMPT.

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.

Print DBMS_OUTPUT.PUT_LINE in a file with a bash script

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

Wrapping a Stored Procedure

I have created a Stored Procedure in Oracle (Via TOAD).
I need to deliver this procedure to some other developers. All is need to do is Wrap the procedure so that at basic level he/she should not be able to view the code.
At the same time, the developer should be able to create the procedure and execute/test it.
my procedure is saved in say FileName.sql whose content are like:
Create or Replace Procedure
IS
Declaration
Begin
Code
End;
Now i want this FileName.sql to be wrapped. So that the encrypted file can be send to other to check in different environment.
Please help me in how to wrap, and then how the other guy will be able to create the procedure, and execute the same.
Thanks in advance.
The Oracle WRAP utility does exactly that - allows you to encode a stored procedure in a form suitable for shipping.
The wrapped code is as portable as source code, but cannot be examined as plain text.
You will need access to the command line using a suitable system user (i.e. one that has access to the Oracle binary commands e.g. sqlplus etc.) and the basic syntax is:
wrap iname=input_file [ oname=output_file ]
If you do not specify any extensions, the default for input is .sql and output is .plb
Once you have generated a .plb file, you can execute it against the database to create your stored procedure.
See:
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/wrap.htm#LNPLS016
http://docs.oracle.com/cd/B10500_01/appdev.920/a96624/c_wrap.htm
WARNING
WRAPencoded procedures are not completely secure - it is possible to "unwrap" them.
A better way of using WRAP is to put the procedure(s) you wish to protect in a package and WRAP the package definition.
Let's say your procedure is:
CREATE OR REPLACE PROCEDURE PR_OUTPUT_TEXT(
P_TYPE IN CHAR,
P_TEXT IN VARCHAR2
) IS
V_TYPE CHAR(3) := UPPER(P_TYPE);
BEGIN
IF V_TYPE = 'LOG' THEN
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.LOG, TO_CHAR(SYSDATE,'HH24:MI:SS')||' - '||P_TEXT);
ELSE
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.OUTPUT, P_TEXT);
END IF;
END PR_OUTPUT_TEXT;
you would normally call it using:
EXECUTE PR_OUTPUT_TEXT('LOG', 'Kittehz!!!')
In a package you would define the package body and the procedure thus:
CREATE OR REPLACE PACKAGE BODY USER.MYPACKAGE AS
PROCEDURE PR_OUTPUT_TEXT(
P_TYPE IN CHAR,
P_TEXT IN VARCHAR2
) IS
BEGIN
IF V_TYPE = 'LOG' THEN
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.LOG, TO_CHAR(SYSDATE,'HH24:MI:SS')||' - '||P_TEXT);
ELSE
APPS.FND_FILE.PUT_LINE(APPS.FND_FILE.OUTPUT, P_TEXT);
END IF;
END PR_OUTPUT_TEXT;
END MYPACKAGE;
and you would call the package using:
EXECUTE USER.MYPACKAGE.PR_OUTPUT_TEXT('LOG', 'ERMAHGERD KERTERNS!!!')
From documentation, to be precise, this is what you need to do :
Running the wrap Utility
For example, assume that the wrap_test.sql file contains the following:
CREATE PROCEDURE wraptest IS
TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;
all_emps emp_tab;
BEGIN
SELECT * BULK COLLECT INTO all_emps FROM employees;
FOR i IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id);
END LOOP;
END;
/
To wrap the file, run the following from the operating system prompt:
wrap iname=wrap_test.sql
The output of the wrap utility is similar to the following:
PL/SQL Wrapper: Release 10.2.0.0.0 on Tue Apr 26 16:47:39 2005
Copyright (c) 1993, 2005, Oracle. All rights reserved.
Processing wrap_test.sql to wrap_test.plb
If you view the contents of the wrap_test.plb text file, the first line is CREATE PROCEDURE wraptest wrapped and the rest of the file contents is hidden.
You can run wrap_test.plb in SQL*Plus to execute the SQL statements in the file:
SQL> #wrap_test.plb
After the wrap_test.plb is run, you can execute the procedure that was created:
SQL> CALL wraptest();
More information in docs

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.