error in pl/sql package body - plsql

I am having this error:
Error(42,22): PLS-00103: Encountered the symbol ")" when expecting one of the following: current
I have written a package with few functions and procedures.
here is my package:
-- specification --
CREATE OR REPLACE PACKAGE SUPERHERO_PACKAGE AS
FUNCTION GET_FULL_SUPERHERONAME(V_SUPERHERONAME IN VARCHAR2)
RETURN VARCHAR2;
PROCEDURE GET_SUPERHEROS(V_CITY IN VARCHAR2);
PROCEDURE GET_ALL_VILLANS;
FUNCTION GET_MAX_XP
RETURN NUMBER;
FUNCTION GET_STRONGEST_SUPERHERO
RETURN VARCHAR2;
END SUPERHERO_PACKAGE;
-- body --
CREATE OR REPLACE PACKAGE BODY SUPERHERO_PACKAGE AS
FUNCTION GET_FULL_SUPERHERONAME(V_SUPERHERONAME IN VARCHAR2)
RETURN VARCHAR2 AS
BEGIN
SELECT FIRST_NAME, LAST_NAME
INTO V_FNAME, V_LNAME
FROM SUPERHERO
WHERE SUPERHERO_NAME = V_SUPERHERONAME;
RETURN (V_FNAME || " " || V_LNAME);
END;
PROCEDURE GET_SUPERHEROS(V_CITY IN VARCHAR2) IS
CURSOR JUSTICE_LEAGUE IS
SELECT SUPERHERO_NAME FROM SUPERHERO WHERE CITY = V_CITY;
LEAGUE_MEMBER JUSTICE_LEAGUE % ROWTYPE;
BEGIN
OPEN JUSTICE_LEAGUE;
LOOP
FETCH JUSTICE_LEAGUE INTO LEAGUE_MEMBER;
EXIT WHEN (JUSTICE_LEAGUE % NOTFOUND);
DBMS_OUTPUT.PUT_LINE(LEAGUE_MEMBER.NAME);
END LOOP;
CLOSE JUSTICE_LEAGUE;
END;
PROCEDURE GET_ALL_VILLANS IS
CURSOR DARK_FORCE IS
SELECT VILLAN FROM SUPERHERO;
FORCE_MEMBER DARK_FORCE % ROWTYPE;
BEGIN
OPEN DARK_FORCE;
LOOP
FETCH DARK_FORCE INTO FORCE_MEMBER;
EXIT WHEN (DARK_FORCE % NOTFOUND);
DBMS_OUTPUT.PUT_LINE(FORCE_MEMBER.VILLAN);
END LOOP;
CLOSE DARK_FORCE;
END;
FUNCTION GET_MAX_XP()
RETURN NUMBER AS
DECLARE
N_XP := 0;
BEGIN
SELECT MAX(XP) INTO N_XP FROM SUPERHERO;
RETURN N_XP;
END;
FUNCTION GET_STRONGEST_SUPERHERO()
RETURN VARCHAR2 AS
DECLARE
V_NAME := 'DNA';
V_FNAME := 'SWAYAM';
V_LNAME := 'RAINA';
BEGIN
SELECT SUPERHERO_NAME, FIRST_NAME, LAST_NAME
INTO V_NAME, V_FNAME, V_LNAME
FROM SUPERHERO
WHERE XP = GET_MAX_XP();
RETURN (V_FNAME || " " || V_LNAME || " AKA " || V_NAME);
END;
END SUPERHERO_PACKAGE;

You code is full of mistakes. Please check below the corrections.
CREATE OR REPLACE PACKAGE SUPERHERO_PACKAGE
AS
FUNCTION GET_FULL_SUPERHERONAME (V_SUPERHERONAME IN VARCHAR2) RETURN VARCHAR2;
PROCEDURE GET_SUPERHEROS (V_CITY IN VARCHAR2);
PROCEDURE GET_ALL_VILLANS;
FUNCTION GET_MAX_XP RETURN NUMBER;
FUNCTION GET_STRONGEST_SUPERHERO RETURN VARCHAR2;
END SUPERHERO_PACKAGE;
-- body --
CREATE OR REPLACE PACKAGE BODY SUPERHERO_PACKAGE
AS
FUNCTION GET_FULL_SUPERHERONAME (V_SUPERHERONAME IN VARCHAR2)
RETURN VARCHAR2 AS
V_FNAME varchar2(1000);
V_LNAME varchar2(1000);
BEGIN
SELECT FIRST_NAME, LAST_NAME
INTO V_FNAME, V_LNAME
FROM SUPERHERO
WHERE SUPERHERO_NAME = V_SUPERHERONAME;
RETURN(V_FNAME||'--'||V_LNAME);
END;
PROCEDURE GET_SUPERHEROS (V_CITY IN VARCHAR2)
IS
CURSOR JUSTICE_LEAGUE(vr_city VARCHAR2) --- parameterized Query
IS
SELECT SUPERHERO_NAME
FROM SUPERHERO
WHERE CITY = vr_city;
LEAGUE_MEMBER JUSTICE_LEAGUE%ROWTYPE;
BEGIN
OPEN JUSTICE_LEAGUE(V_CITY); --This is the way to call.
LOOP
FETCH JUSTICE_LEAGUE INTO LEAGUE_MEMBER;
EXIT WHEN JUSTICE_LEAGUE%NOTFOUND; -- No brackets needed
DBMS_OUTPUT.PUT_LINE(LEAGUE_MEMBER.SUPERHERO_NAME);
END LOOP;
CLOSE JUSTICE_LEAGUE;
END;
PROCEDURE GET_ALL_VILLANS
IS
CURSOR DARK_FORCE
IS
SELECT VILLAN
FROM SUPERHERO;
FORCE_MEMBER DARK_FORCE%ROWTYPE;
BEGIN
OPEN DARK_FORCE;
LOOP
FETCH DARK_FORCE INTO FORCE_MEMBER;
EXIT WHEN DARK_FORCE%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (FORCE_MEMBER.VILLAN);
END LOOP;
CLOSE DARK_FORCE;
END;
FUNCTION GET_MAX_XP
RETURN NUMBER
AS
N_XP number:= 0; --Never use declare here
BEGIN
SELECT MAX (XP) INTO N_XP FROM SUPERHERO;
RETURN N_XP;
END;
FUNCTION GET_STRONGEST_SUPERHERO
RETURN VARCHAR2
AS
V_NAME varchar2(1000) := 'DNA'; --------Declaration Missing
V_FNAME varchar2(1000) := 'SWAYAM';
V_LNAME varchar2(1000) := 'RAINA';
BEGIN
SELECT SUPERHERO_NAME, FIRST_NAME, LAST_NAME
INTO V_NAME, V_FNAME, V_LNAME
FROM SUPERHERO
WHERE XP = (SELECT GET_MAX_XP() from dual); ----general practrice to call a function in where clause
RETURN (V_FNAME||' '||V_LNAME||'AKA'||V_NAME); --no double quotes
END;
END SUPERHERO_PACKAGE;

Related

returning value to cursor plsql

Hi I have a procedure which return a recordset using cursor in output what am trying to do is i use cursor to get the data and same have to return it to output cursor .I can do like below
PROCEDURE test(value_one IN someTabel.somecolumn%TYPE,
valu_two IN someTabel.somecolumn%TYPE,
Outputcursor OUT SYS_REFCURSOR) IS
mydeclaration goes here
output_value_one sometable.somecolumn%Type;
---
cursor test_select is
select statement
begin
for val in test_select loop
fetch test_select into output_value_one; -- I want my cursor outputcursor to be return instead of output_value_one
end loop;
end;
You send the deptno the cursor return the query where you can handle from frontend.
create or replace Procedure Transproc(p_deptno IN emp.deptno%TYPE,
Outputcursor Out Sys_Refcursor,
p_recordset Out Varchar)
Is
Vquery varchar2(200);
Begin
Vquery:='select * from emp where deptno='|| p_deptno ||'';
Open Outputcursor For Vquery;
OMessage:='Success';
Exception
When others then
OMessage:='Fail';
End;
OR try below one as per your requriement.
CREATE OR REPLACE PROCEDURE get_emp_rs (p_deptno IN emp.deptno%TYPE,
p_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN p_recordset FOR
SELECT ename,
empno,
deptno
FROM emp
WHERE deptno = p_deptno
ORDER BY ename;
END GetEmpRS;
/
To test :-
SET SERVEROUTPUT ON SIZE 1000000
DECLARE
l_cursor SYS_REFCURSOR;
l_ename emp.ename%TYPE;
l_empno emp.empno%TYPE;
l_deptno emp.deptno%TYPE;
BEGIN
get_emp_rs (p_deptno => 30,
p_recordset => l_cursor);
LOOP
FETCH l_cursor
INTO l_ename, l_empno, l_deptno;
EXIT WHEN l_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(l_ename || ' | ' || l_empno || ' | ' || l_deptno);
END LOOP;
CLOSE l_cursor;
End;
/

F_checksal is not a procedure or is undefined when compiling plsql

When I am trying to compile this plsql I keep getting this error message:
'F_checksal is not a procedure or is undefined'
This is the code:
declare
e_high_increase EXCEPTION;
old_sal NUMBER;
function f_checkSal(i_sal number,i_old_sal IN OUT NUMBER) return VARCHAR2 is
begin
if((i_sal/old_sal)*100>300) then
raise e_high_increase;
else
return 'yes';
end if;
exception when e_high_increase then
insert into t_logerror(error_tx) values ('this is user exception');
dbms_output.put_line('this is user exception');
return 'No';
end;
begin
select sal into old_sal FROM emp where empno=153;
f_checksal(30000,old_sal);
update emp set sal=30000 where empno=153;
end;
It's just your call to your function that needs to be changed.
You can consume the result with a call to a procedure (e.g. DBMS_OUTPUT.put_line( f_checksal(30000,old_sal));), or assign it to a local variable, e.g. RESULT := f_checksal(30000,old_sal);
Your syntax is way off. You need to first CREATE the function, then reference it in your pl/sql block:
Step1 :
CREATE OR REPLACE FUNCTION f_checksal (i_sal NUMBER, i_old_sal IN OUT NUMBER)
RETURN VARCHAR2
IS
old_sal NUMBER;
e_high_increase EXCEPTION;
BEGIN
IF ((i_sal / old_sal) * 100 > 300)
THEN
RAISE e_high_increase;
ELSE
RETURN 'yes';
END IF;
EXCEPTION
WHEN e_high_increase
THEN
INSERT INTO t_logerror
(error_tx
)
VALUES ('this is user exception'
);
DBMS_OUTPUT.put_line ('this is user exception');
RETURN 'No';
END;
/
Step 2:
DECLARE
old_sal NUMBER;
RESULT VARCHAR2 (100);
BEGIN
SELECT sal
INTO old_sal
FROM emp
WHERE empno = 153;
RESULT := f_checksal (30000, old_sal);
UPDATE emp
SET sal = 30000
WHERE empno = 153;
END;
Note that your function has a return value that you were not assinging in the calling code.

TOAD displaying cursor recordset returned by stored procedure

How I could print recorset result from the returning cursor, please.
Down below executes fine but I need to see result.
This is block in TOAD, calling package sp AMD_NEEDMSG:
DECLARE
RETURN_RECORDSET CTI_MATRIX.AMD.REF_CURSOR;
BEGIN
CTI_MATRIX.AMD.AMD_NEEDMSG ( '88888888885', RETURN_RECORDSET );
END;
This package spec:
CREATE OR REPLACE PACKAGE CTI_MATRIX.AMD AS
TYPE REF_CURSOR IS REF CURSOR;
PROCEDURE AMD_NEEDMSG (v_CRN IN VARCHAR2, return_recordset OUT REF_CURSOR);
END AMD;
This is package body:
CREATE OR REPLACE PACKAGE BODY CTI_MATRIX.AMD AS
PROCEDURE AMD_NEEDMSG (v_CRN IN VARCHAR2, return_recordset OUT REF_CURSOR) IS
return_flag INTEGER;
row_cnt INTEGER;
number_of_days INTEGER;
var_DATE DATE;
CURSOR ACCNTSEARCH (P_CRN IN VARCHAR2) IS
SELECT DISTINCT COUNT(*) , AMD.MSG_DATE
FROM TBL_AMD_NEEDMSG AMD
WHERE AMD.PHONE_NUMBER = P_CRN AND ROWNUM = 1;
BEGIN
OPEN ACCNTSEARCH(v_CRN);
FETCH ACCNTSEARCH INTO row_cnt, var_DATE;
CLOSE ACCNTSEARCH;
IF (row_cnt = 0)
THEN
INSERT INTO TBL_AMD_NEEDMSG (PHONE_NUMBER, MSG_DATE) VALUES (v_CRN , SYSDATE);
return_flag := 1;
ELSE
SELECT SYSDATE-var_DATE INTO number_of_days FROM dual;
IF (number_of_days>7)
THEN
UPDATE TBL_AMD_NEEDMSG SET MSG_DATE = SYSDATE WHERE PHONE_NUMBER = v_CRN;
return_flag := 1;
ELSE
return_flag := 0;
END IF;
END IF;
COMMIT;
OPEN return_recordset FOR
SELECT return_flag AS ReturnFLag FROM DUAL;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
END AMD_NEEDMSG;
END AMD;
/
Bottom line is to return to client a value of return_flag in the form of record set.
To return the return_flag, which is int=1 or 0 you need function that returns a single value, not recordset. Below are general recordset examples - hope this helps:
DECLARE
TYPE empcurtyp IS REF CURSOR;
emp_cv empcurtyp;
--
TYPE namelist IS TABLE OF scott.emp.ename%TYPE;
TYPE sallist IS TABLE OF scott.emp.sal%TYPE;
names namelist;
sals sallist;
BEGIN
OPEN emp_cv FOR
SELECT ename, sal FROM scott.emp
WHERE job = 'MANAGER' ORDER BY sal DESC;
--
FETCH emp_cv BULK COLLECT INTO names, sals;
CLOSE emp_cv;
-- loop through the names and sals collections
FOR i IN names.FIRST .. names.LAST LOOP
DBMS_OUTPUT.PUT_LINE
('Name = ' || names(i) || ', salary = ' || sals(i));
END LOOP;
END;
/
-- SYS_REFCURSOR example --
DECLARE
p_rc_type SYS_REFCURSOR;
emp_rec scott.emp%ROWTYPE;
--
PROCEDURE p_Emp_Info (p_cur_var OUT SYS_REFCURSOR)
IS
BEGIN
OPEN p_cur_var FOR
SELECT ename, job FROM scott.emp WHERE job = 'MANAGER';
LOOP
FETCH p_cur_var INTO emp_rec.ename, emp_rec.job;
EXIT WHEN p_cur_var%NOTFOUND;
dbms_output.put_line(emp_rec.ename ||' '|| emp_rec.job);
END LOOP;
CLOSE p_cur_var;
END p_Emp_Info;
--
BEGIN
p_Emp_Info(p_rc_type);
END;
/

How to solve the Issue declaring a cursor in a Procedure/Package?

I'm new to Oracle and having issues declaring a cursor within my package. Can anyone tell me what i'm doing wrong?
Thanks
CREATE OR REPLACE PACKAGE CHECK_STOCK_LEVELS AS
PROCEDURE CHECK_PAYMTS_AGAINST_INVOICES;
FUNCTION CHECK_PROD_PRICE RETURN NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY CHECK_STOCK_LEVELS AS
FUNCTION CHECK_PROD_PRICE (INP_PROD_NAME VARCHAR2)
RETURN NUMBER
IS
PROD_CNT PRODUCT.PROD_NAME%TYPE;
BEGIN
SELECT PROD_PRICE INTO PROD_CNT
FROM PRODUCT WHERE PROD_PRICE = INP_PROD_NAME;
RETURN (PROD_CNT);
END CHECK_PROD_PRICE;
/
SELECT CHECK_STOCK_LEVELS.CHECK_PROD_PRICE(3.5mm Jack) FROM DUAL;
PROCEDURE CHECK_PAYMTS_AGAINST_INVOICES
DECLARE CURSOR SEL_PAYMTS_AND_INVS
IS
SELECT P.INVOICE_ID, P.PAYMENT_AMOUNT, I.INVOICE_AMOUNT
FROM PAYMENT P
INNER JOIN INVOICE I ON P.INVOICE_ID = I.INVOICE_ID;
V_TEMP_RESULTS_ROW SEL_PAYMTS_AND_INVS%ROWTYPE;
PAYMT_INVOICE_MISMATCH EXCEPTION;
BEGIN
OPEN SEL_PAYMTS_AND_INVS;
FETCH SEL_PAYMTS_AND_INVS INTO V_TEMP_RESULTS_ROW;
WHILE SEL_PAYMTS_AND_INVS%FOUND LOOP
IF V_TEMP_RESULTS_ROW.PAYMENT_AMOUNT != V_TEMP_RESULTS_ROW.INVOICE_AMOUNT THEN
DBMS_OUTPUT.PUT_LINE('EMPLOYEE ID : ' || V_EMPLOYEE_ROW.EMPID || ' HAS A SALARY OF : ' || V_EMPLOYEE_ROW.SALARY);
RAISE PAYMT_INVOICE_MISMATCH;
END IF;
FETCH SEL_PAYMTS_AND_INVS INTO V_TEMP_RESULTS_ROW;
END LOOP;
CLOSE SEL_PAYMTS_AND_INVS;
EXCEPTION
WHEN PAYMT_INVOICE_MISMATCH THEN
DBMS_OUTPUT.PUT_LINE('PAYMENT AMOUNT DOES NOT MATCH INVOICE AMOUNT');
RAISE;
END;
END;
This:
SELECT CHECK_STOCK_LEVELS.CHECK_PROD_PRICE(3.5mm Jack) FROM DUAL;
should be:
SELECT CHECK_STOCK_LEVELS.CHECK_PROD_PRICE('3.5mm Jack') FROM DUAL;
And this:
PROCEDURE CHECK_PAYMTS_AGAINST_INVOICES
DECLARE CURSOR SEL_PAYMTS_AND_INVS
IS
SELECT P.INVOICE_ID, P.PAYMENT_AMOUNT, I.INVOICE_AMOUNT
FROM PAYMENT P
INNER JOIN INVOICE I ON P.INVOICE_ID = I.INVOICE_ID;
V_TEMP_RESULTS_ROW SEL_PAYMTS_AND_INVS%ROWTYPE;
PAYMT_INVOICE_MISMATCH EXCEPTION;
BEGIN
...
should be:
PROCEDURE CHECK_PAYMTS_AGAINST_INVOICES
IS -- not DECLARE
CURSOR SEL_PAYMTS_AND_INVS
IS
SELECT P.INVOICE_ID, P.PAYMENT_AMOUNT, I.INVOICE_AMOUNT
FROM PAYMENT P
INNER JOIN INVOICE I ON P.INVOICE_ID = I.INVOICE_ID;
V_TEMP_RESULTS_ROW SEL_PAYMTS_AND_INVS%ROWTYPE;
PAYMT_INVOICE_MISMATCH EXCEPTION;
BEGIN
...

How to write to files using utl_file in oracle

How to use put function.my procedure is not compiling with put. but putline is working fine. i want to print in the same line
Here's an example of code which uses the UTL_FILE.PUT and UTL_FILE.PUT_LINE calls:
declare
fHandle UTL_FILE.FILE_TYPE;
begin
fHandle := UTL_FILE.FOPEN('my_directory', 'test_file', 'w');
UTL_FILE.PUT(fHandle, 'This is the first line');
UTL_FILE.PUT(fHandle, 'This is the second line');
UTL_FILE.PUT_LINE(fHandle, 'This is the third line');
UTL_FILE.FCLOSE(fHandle);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Exception: SQLCODE=' || SQLCODE || ' SQLERRM=' || SQLERRM);
RAISE;
end;
The output from this looks like:
This is the first lineThis is the second lineThis is the third line
Share and enjoy.
Here is a robust function for using UTL_File.putline that includes the necessary error handling. It also handles headers, footers and a few other exceptional cases.
PROCEDURE usp_OUTPUT_ToFileAscii(p_Path IN VARCHAR2, p_FileName IN VARCHAR2, p_Input IN refCursor, p_Header in VARCHAR2, p_Footer IN VARCHAR2, p_WriteMode VARCHAR2) IS
vLine VARCHAR2(30000);
vFile UTL_FILE.file_type;
vExists boolean;
vLength number;
vBlockSize number;
BEGIN
UTL_FILE.fgetattr(p_path, p_FileName, vExists, vLength, vBlockSize);
FETCH p_Input INTO vLine;
IF p_input%ROWCOUNT > 0
THEN
IF vExists THEN
vFile := UTL_FILE.FOPEN_NCHAR(p_Path, p_FileName, p_WriteMode);
ELSE
--even if the append flag is passed if the file doesn't exist open it with W.
vFile := UTL_FILE.FOPEN(p_Path, p_FileName, 'W');
END IF;
--GET HANDLE TO FILE
IF p_Header IS NOT NULL THEN
UTL_FILE.PUT_LINE(vFile, p_Header);
END IF;
UTL_FILE.PUT_LINE(vFile, vLine);
DBMS_OUTPUT.PUT_LINE('Record count > 0');
--LOOP THROUGH CURSOR VAR
LOOP
FETCH p_Input INTO vLine;
EXIT WHEN p_Input%NOTFOUND;
UTL_FILE.PUT_LINE(vFile, vLine);
END LOOP;
IF p_Footer IS NOT NULL THEN
UTL_FILE.PUT_LINE(vFile, p_Footer);
END IF;
CLOSE p_Input;
UTL_FILE.FCLOSE(vFile);
ELSE
DBMS_OUTPUT.PUT_LINE('Record count = 0');
END IF;
EXCEPTION
WHEN UTL_FILE.INVALID_PATH THEN
DBMS_OUTPUT.PUT_LINE ('invalid_path');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
WHEN UTL_FILE.INVALID_MODE THEN
DBMS_OUTPUT.PUT_LINE ('invalid_mode');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
WHEN UTL_FILE.INVALID_FILEHANDLE THEN
DBMS_OUTPUT.PUT_LINE ('invalid_filehandle');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
WHEN UTL_FILE.INVALID_OPERATION THEN
DBMS_OUTPUT.PUT_LINE ('invalid_operation');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
WHEN UTL_FILE.READ_ERROR THEN
DBMS_OUTPUT.PUT_LINE ('read_error');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
WHEN UTL_FILE.WRITE_ERROR THEN
DBMS_OUTPUT.PUT_LINE ('write_error');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
WHEN UTL_FILE.INTERNAL_ERROR THEN
DBMS_OUTPUT.PUT_LINE ('internal_error');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('other write error');
DBMS_OUTPUT.PUT_LINE(SQLERRM);
RAISE;
END;
You can check the below example of how to log/write using utl_file in PL/SQL.
DECLARE
fhandle utl_file.file_type;
BEGIN
fhandle := utl_file.fopen(
'UTL_DIR_STACKOVERFLOW'-- File location
, 'Check_Logging.txt' -- File name
, 'a' -- Open mode: a = append, w = write
);
utl_file.put(fhandle, 'Stackoverflow' );
utl_file.fclose(fhandle);
END;
Problems you can face-
Invalid directory object
Then you can create your own directory object and use the below query.
create or replace directory UTL_DIR_STACKOVERFLOW as '/tmp/';
CREATE OR REPLACE PROCEDURE SP_EXPORT_TO_CSV(P_OWNER VARCHAR2,
P_OBJECT_NAME VARCHAR2,
P_FILE_NAME VARCHAR2 --,
-- P_DELIMITED CHAR
) AS
-- declaration
TYPE C_DATA_CURSOR IS REF CURSOR;
C_DATA C_DATA_CURSOR;
v_file UTL_FILE.FILE_TYPE;
V_COLUMNS VARCHAR2(32767);
X VARCHAR2(32767);
V_FILE_NAME VARCHAR2(2000);
V_OWNER VARCHAR2(100);
V_OBJECT_NAME VARCHAR2(1000);
V_SQL VARCHAR2(32767);
V_DELIMITED VARCHAR2(10);
BEGIN
-- set value
V_FILE_NAME := P_FILE_NAME;
V_OBJECT_NAME := P_OBJECT_NAME;
V_OWNER := P_OWNER;
--V_DELIMITED:=P_DELIMITED;
SELECT REPLACE(LISTAGG(COLUMN_NAME, '|') WITHIN
GROUP(ORDER BY COLUMN_ID),
'|',
' || ' || '''|''' || ' || ')
INTO V_COLUMNS
FROM ALL_TAB_COLUMNS W
WHERE W.TABLE_NAME = V_OBJECT_NAME
AND W.OWNER = V_OWNER
ORDER BY COLUMN_ID;
-- SET OUTPUT PARAMETER --'EXPORTED_TO_TEXT_LOCATION'
v_file := UTL_FILE.FOPEN(location => 'MYLOCATION',
filename => V_FILE_NAME,
open_mode => 'w',
max_linesize => 32767);
UTL_FILE.PUT_LINE(v_file, REPLACE(V_COLUMNS, ' || ''|'' || ', '|'));
X := 'SELECT ' || V_COLUMNS || ' AS RECORD FROM ' || V_OWNER || '.' ||
V_OBJECT_NAME;
OPEN C_DATA FOR X;
LOOP
FETCH C_DATA
INTO V_SQL;
EXIT WHEN C_DATA%NOTFOUND;
UTL_FILE.PUT_LINE(v_file, V_SQL);
END LOOP;
CLOSE C_DATA;
UTL_FILE.FCLOSE(v_file);
END;

Resources