Plsql refcursor
10.2 RAC (4 node), OS= Solaris.
Here's an example function:
DECLARE
results_cur SYS_REFCURSOR;
results_id NUMBER;
FUNCTION getData RETURN SYS_REFCURSOR IS
ref_cur SYS_REFCURSOR;
BEGIN
OPEN ref_cur FOR
SELECT ......
FROM tab_1 t1
,tab_2 t2
WHERE t1.id = t2.fkid
AND t1.id = :ID
AND t2.start_date BETWEEN :date_1 AND :date_2
RETURN ref_cur;
END;
BEGIN
results_cur := getData;
LOOP
FETCH results_cur
INTO results_id;
EXIT WHEN results_cur%NOTFOUND;
END LOOP;
CLOSE results_cur;
EXCEPTION
WHEN OTHERS THEN
CLOSE results_cur;
END;
Ignore any syntax errors :)
Here's the funny thing - It runs fast when sql_trace is on but runs slow when sql_trace is turned off?
It's hard to find out the culprit when I can't use sql_trace.
Steven
that was a really facinating read - in case the OP misses it, in the comments on that blog post, Tom links to a follow up post with some actual possible solutions.
http://tkyte.blogspot.com/2007/09/sqltracetrue-part-two.html
Similar Messages
-
How to call a procedure with refcursor from another plsql unit
example I created a pkg with the a procedure that returns a REFCURSOR.
Now I need to call this procedure from another pkg and use the refcursor values in other pkg.
Help please.......
PROCEDURE CustomerSite_Get (p_Registry IN VARCHAR2,
p_CustomerNumber IN VARCHAR2, p_Cursor IN OUT t_cursor);
PROCEDURE CustomerSite_Get (p_Registry IN VARCHAR2,
p_CustomerNumber IN VARCHAR2, p_Cursor IN OUT t_cursor)
IS
-- 0903: Include BillToName
BEGIN
OPEN p_Cursor FOR
SELECT S.LOCATION CustomerSite, S.SITE_USE_ID CustomerSiteID, C.CUSTOMER_NAME BillToName
FROM RA_CUSTOMERS C,
RA_ADDRESSES A,
RA_SITE_USES S,
UWA_REGISTRY R,
UWA_REGISTRY_BILL_TO B
WHERE C.CUSTOMER_ID = A.CUSTOMER_ID
AND A.ADDRESS_ID = S.ADDRESS_ID
AND S.SITE_USE_ID = B.SITE_USE_ID
AND R.REGISTRY_ID = B.REGISTRY_ID
AND B.TRIP_BILLING != 'N'
AND R.DELETE_FLAG != 'Y'
AND R.Registry = p_Registry
AND R.CUSTOMER_NUM = p_CustomerNumber
ORDER BY S.LOCATION;
END CustomerSite_Get;
thanks,
Anitha.
Edited by: user521218 on May 6, 2009 1:24 PMHi Anitha,
try this,
-- PKG_A
Procedure CustomerSite_Get( p_Registry IN Varchar2
, p_CustomerNumber IN Varchar2
, p_Cursor IN OUT t_cursor) Is
Begin
PKG_B.CustomerSite_Get( p_Registry
, p_CustomerNumber
, p_Cursor );
End;
-- PKG_B
Procedure CustomerSite_Get(p_Registry IN Varchar2
,p_CustomerNumber IN Varchar2
,p_Cursor IN OUT t_cursor) Is
Begin
Open p_Cursor For
SELECT S.LOCATION CustomerSite
,S.SITE_USE_ID CustomerSiteID
,C.CUSTOMER_NAME BillToName
FROM RA_CUSTOMERS C
,RA_ADDRESSES A
,RA_SITE_USES S
,UWA_REGISTRY R
,UWA_REGISTRY_BILL_TO B
WHERE C.CUSTOMER_ID = A.CUSTOMER_ID
AND A.ADDRESS_ID = S.ADDRESS_ID
AND S.SITE_USE_ID = B.SITE_USE_ID
AND R.REGISTRY_ID = B.REGISTRY_ID
AND B.TRIP_BILLING != 'N'
AND R.DELETE_FLAG != 'Y'
AND R.Registry = p_Registry
AND R.CUSTOMER_NUM = p_CustomerNumber
Order BY S.LOCATION;
End CustomerSite_Get;regards,
Christian Balz -
Getting ~ saperated values in to plsql tables or refcursor
Hi<br>
<br>
If have a column with ~ saperated value as <br>
<br>
pen~pencil~rubber <br>
<br>
This string does not have fixed number of ~ in the string column how can i <br>saperate these values and store it in plsql table or ref cursor .
can i get this using sql statement <br>
for ex
i want that in similar fashion in plsql table
<br>
pen <br>
pecil<br>
rubber<br>
<br>
<br>
Can i get what is the number of ~ in the above string using sql statement<br>
<br>
Regards<br>
vamsi krishnaThis string does not have fixed number of ~ in the string column how can isaperate these values and store it in plsql
SCOTT@demo102> drop table tild;
Table dropped.
SCOTT@demo102> create table tild (id number, text varchar2(20));
Table created.
SCOTT@demo102>
SCOTT@demo102> insert into tild values (1,'pen~pencil~rubber');
1 row created.
SCOTT@demo102> insert into tild values (2,'ent~stand~expr');
1 row created.
SCOTT@demo102> insert into tild values (3,'rugby~football');
1 row created.
SCOTT@demo102>
SCOTT@demo102> set serveroutput on
SCOTT@demo102>
SCOTT@demo102> declare
2 type mytype is table of varchar2(20);
3 mytable mytype:=mytype();
4 mystr varchar2(20);
5 i number:=0;
6 begin
7 for x in (select text from tild) loop
8 mystr:=x.text||'~';
9 while instr(mystr,'~')>0 loop
10 i:=i+1;
11 mytable.extend(1);
12 mytable(i):=substr(mystr,1,instr(mystr,'~')-1);
13 mystr:=substr(mystr,instr(mystr,'~')+1);
14 dbms_output.put_line(mytable(i));
15 end loop;
16 end loop;
17 end;
18 /
pen
pencil
rubber
ent
stand
expr
rugby
football
PL/SQL procedure successfully completed.
SCOTT@demo102> Nicolas. -
Refcursor return set in plsql in oracle 10.2.0.4.0 db -
I am writing a function which returns the result set to front end application. it all works fine for existing rec but it returs bad/awkward message when non exiting rec is given...
declare
user_cur SYS_REFCURSOR;
BEGIN
OPEN user_cur FOR
SELECT pwd,
first_name,
last_name
FROM XS_user
WHERE u_id = i_u_id;
FETCH user_cur
INTO l_pwd,
l_f_n
l_l_n
IF (user_cur%NOTFOUND)
THEN
---- return false ; -- does not work!!?!?
RAISE_APPLICATION_ERROR (-20001, 'No User Id ');
END IF;
return user_cur;
end;
i want to return result set when matching record found and need to return nothing when no record found.. but it says for nonexisting rec is
ORA-06503: PL/SQL: Function returned without value
ORA-06512: at "xxxx.xxx_xxx_xxx", line 353
ORA-06512: at line 1
Script Terminated on line 4.
I need into clause as i need to check other conditions on data
would you please suggest how to return nothing when no matching record found..?knowledgespring wrote:
here is full picture of code i am writingSeveral problems with the code. There is not need for an explicit cursor, never mind a ref cursor. If you expect a single row, then code for that. More rows will be a fail. And that will raise an exception as it should. Exceptions are good.
Also be very careful with ref cursors. The PL/SQL engine does not close these cursor handles for you - so if you do not explicitly close ref cursors, your code will be leaking cursor handles and causing resource problems.
Also, do not code the same conditional processing structures again and again:
if db_pass!=pwd then
raise_application_error(-20001,'password wrong');
end if;Modularise it. Look again at the reference I posted in my previous response and at how the Assert() procedure is used to modularise such conditional processing blocks (and how error codes and messages are treated as data - as that is what they are).
And once modularised - easy to use. Easy to maintain. Easy to enhance. For example, you need to log application exceptions via an autonomous transaction to an error log table? A single change to the code is needed. Why? Because a single procedure is used to raise custom application errors. Instead of having to hunt through the type of code you've posted, looking for all the raise_application_error() calls scattered throughout the code.
The sample code I referred to shows exactly how requirements like yours should be addressed. Modularised code that is readable and maintainable with minimal effort.
It is one of the worse programming sins to approach a problem by not modularising. It is wrong to throw all the code into a single code unit and turning it into a complex and monolithic monster. And that is why your code does not work and are full of errors.
Keep it simple. Create simplistic building blocks, like Assert() and RaiseError() procedures. Then use these blocks to build a complex process. The end-result might be a complex process, but one that is easy to understand, take apart, re-assemble, modify, enhance and maintain, because it consists of simple building blocks.
And that is why software development is called software engineering. Basic engineering principles apply in writing robust and scalable software. Principles you can either take to heart and apply.. or not - and continue designing and writing software messes... (and I wish someone preached this to me as a junior programmer and I did not have to learn these lessons the hard way) -
Accessing a sys refcursor as a plsql out parameter
The 11g jdbc guide gives and example of how to access a pl/sql function RETURNING a cursor. We have a stored proc that returns about 5 out parameters one of which is a SYS_REFCURSOR. This is different from RETURNING a ref cursor. Can someone please help me with how to pass a resultset object to the stored proc. I presume the same java declaration is required:
ResultSet cursor;
pass this as a parameter to the stored proc. I have listed the 11g JDBC sample code below:
import oracle.jdbc.*;
CallableStatement cstmt;
ResultSet cursor;
// Use a PL/SQL block to open the cursor
********** HIMANSHU reaplce this with the name of my stored proc dennis1.pkg_snapitall ****************
cstmt = conn.prepareCall
("begin open ? for select ename from emp; end;");
cstmt.registerOutParameter(1, OracleTypes.CURSOR);
cstmt.execute();
cursor = ((OracleCallableStatement)cstmt).getCursor(1);
// Use the cursor like a standard ResultSet
while (cursor.next ())
{System.out.println (cursor.getString(1));}
In the preceding example:
• A CallableStatement object is created by using the prepareCall method of the connection class.
• The callable statement implements a PL/SQL procedure that returns a REF CURSOR.
• As always, the output parameter of the callable statement must be registered to define its type. Use the type code OracleTypes.CURSOR for a REF CURSOR.
• The callable statement is run, returning the REF CURSOR.
• The CallableStatement object is cast to OracleCallableStatement to use the getCursor method, which is an Oracle extension to the standard JDBC API, and returns the REF CURSOR into a ResultSet object.public void readSysRef() throws SQLException {
try {
OracleCallableStatement stmt = (OracleCallableStatement)
// both are ok.
//NOTE: when using call, add ";" after get_empployees() will fail
//connect.prepareCall("{ call ? := get_employees( ? ) }");
connect.prepareCall("begin ? := get_employees( ? ); end;");
stmt.registerOutParameter(1, OracleTypes.CURSOR);
stmt.setInt( 2, 10000);
stmt.execute();
OracleResultSet rs = (OracleResultSet) stmt.getCursor(1);
while (rs.next()) {
System.out.format("Employee %1$s has salary %2$d.%n",
rs.getString(1), rs.getInt(2));
} catch (SQLException e) {
throw e;
} -
How to fetch from cursor into plsql collection
Dear Friends,
I am trying to understand PLSQL collections. I am trying with the following example.
CREATE OR REPLACE TYPE emp_obj AS OBJECT
( empname VARCHAR2(100), empjob VARCHAR2(50), empsal NUMBER);
CREATE OR REPLACE TYPE emp_tbl IS TABLE OF emp_obj;
CREATE OR REPLACE PACKAGE eg_collection AS
-- Delcare ref cursor
TYPE rc IS REF CURSOR;
-- Procedure
PROCEDURE eg_collection_proc (out_result OUT rc);
END;
CREATE OR REPLACE PACKAGE BODY eg_collection AS
PROCEDURE eg_collection_proc( out_result OUT rc) AS
emp_tdt emp_tbl := emp_tbl(emp_obj('oracle','DBA',100));
CURSOR c2 IS SELECT ename,job,sal FROM emp WHERE sal > 2000;
-- Declare a record type to hold the records from cursor and then pass to the collection
emp_rec emp_obj;
BEGIN
OPEN c2;
LOOP FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
emp_tdt.extend;
emp_tdt(emp_tdt.count) := emp_rec;
END LOOP;
CLOSE c2;
OPEN out_result FOR SELECT * FROM TABLE(CAST(emp_tdt AS emp_tbl));
END eg_collection_proc;
END eg_collection;
Executing the proc
variable r refcursor;
exec eg_collection.eg_collection_proc(:r);
print r;
But I am getting compilation error type mismatch found at emp_rec between fetch cursor into variableI am trying to understand PLSQL collections. I dont why the code is not working
SQL> CREATE OR REPLACE TYPE emp_obj AS OBJECT
2 (
3 empname VARCHAR2(100),
4 empjob VARCHAR2(50),
5 empsal NUMBER
6 )
7 /
Type created.
SQL> CREATE OR REPLACE TYPE emp_tbl IS TABLE OF emp_obj
2 /
Type created.
SQL> DECLARE
2 emp_tdt emp_tbl := emp_tbl ();
3 BEGIN
4
5 emp_tdt.extend;
6 SELECT emp_obj(ename, job, sal) BULK COLLECT INTO emp_tdt
7 FROM emp WHERE sal < 4000;
8
9 DBMS_OUTPUT.PUT_LINE ('The total count is ' || emp_tdt.count);
10
11 emp_tdt.extend;
12 SELECT ename, job, sal INTO emp_tdt(1).empname, emp_tdt(1).empjob, emp_tdt(1).empsal
13 FROM emp WHERE empno = 7900;
14
15 DBMS_OUTPUT.PUT_LINE ('The total count is ' || emp_tdt.count);
16
17 END;
18 /
The total count is 13
The total count is 14
PL/SQL procedure successfully completed.
SQL> DECLARE
2 emp_tdt emp_tbl := emp_tbl ();
3 BEGIN
4
5 emp_tdt.extend;
6 SELECT ename, job, sal INTO emp_tdt(1).empname, emp_tdt(1).empjob, emp_tdt(1).empsal
7 FROM emp WHERE empno = 7900;
8
9 DBMS_OUTPUT.PUT_LINE ('The total count is ' || emp_tdt.count);
10
11 emp_tdt.extend;
12 SELECT emp_obj(ename, job, sal) BULK COLLECT INTO emp_tdt
13 FROM emp WHERE sal < 4000;
14
15 DBMS_OUTPUT.PUT_LINE ('The total count is ' || emp_tdt.count);
16 END;
17 /
DECLARE
ERROR at line 1:
ORA-06530: Reference to uninitialized composite
ORA-06512: at line 6 -
How to use LIKE operator in plsql
Hi
I wanted to select certain rows using like operator in plsql(Input should be given by the user). I have given my experiment here .I couldn't get any result.
As per sql syntax while using LIKE operator we should give search criteria within single quote.where as in plsql if we give within single quote its takes as string so no output is comming.what is solution ? How to use like operator in plsql?
sql syntax
SQL>SELECT customer_name FROM customer_header
WHERE customer_name LIKE 'B%' ; customer_name
Bala murali
Babu
Basker
plsql syntax
PROCEDURE pro_custheader_like ( v_cname IN varchar2
,answer OUT type_refcur_customer) IS
BEGIN
OPEN answer FOR
SELECT customer_name FROM customer_header
WHERE customer_name LIKE ( ' v_cname ' );
END pro_custheader_like;
execution command
sql>variable answer refcursor;
sql>set serveroutput on
sql>exec package_name.pro_custheader_like( 'R',:answer);
plsql successfully completed
sql>print :answer
no row selected
by
balamuralikrishnan.splsql syntax
PROCEDURE pro_custheader_like ( v_cname IN
varchar2
,answer OUT
type_refcur_customer) IS
N
OPEN answer FOR
SELECT customer_name FROM customer_header
WHERE customer_name LIKE ( v_cname );
END pro_custheader_like;
Try it without any quotes. And, let us know your feedback.
Regards.
Satyaki De.
Message was edited by:
Satyaki_De -
How to pass int array as an IN parameter to PLSQL Procedure
Hi,
How to pass int array in java to a stored procedure througn jdbc
and what type of data type I should declare to this IN parameter
in PLSQL Procedure.
Thanks,
SimiHi,
The best way to do what you want depends on what you want. Start by describing what you need to do. It's best to post some sample data (CREATE TABLE and INSERT statments) and what results you want from that sample data. (See the forum FAQ: https://forums.oracle.com/message/9362002)
If you have ideas about how to do the job (e.g., populating a temporary table) it can be helpful to include those, too, but distinguish clearly between WHAT you need to do and HOW you might do it.
As Bencol suggested, a SYS_REFCURSOR might be the best way to pass back the results.
Since you didn't post your table, or even describe what you wanted to do with it, I'll illustrate using scott.emp, which is probably on your system.
Say you wanted a procedure that took a DATE as an argument, and returned a some designated columns (empno, ename and hiredate in the example below) for all employees hired on or after the given DATE. You might write a procedure like this:
CREATE OR REPLACE PROCEDURE hired_since
( start_date IN DATE
, out_data OUT SYS_REFCURSOR
AS
BEGIN
OPEN out_data FOR
SELECT empno, ename, hiredate
FROM scott.emp
WHERE hiredate >= start_date;
END hired_since;
SHOW ERRORS
You can test it in SQL*Plus like this:
VARIABLE c REFCURSOR
EXEC hired_since (DATE '1982-01-01', :c);
PRINT :c
The output I got from this test was:
EMPNO ENAME HIREDATE
7788 SCOTT 19-APR-87
7876 ADAMS 23-MAY-87
7934 MILLER 23-JAN-82 -
Help required in PLSQL Procedure.
Hi All,
I am writing a procedure in PLSQL, based on user input(user will input table name) we have to do a select * from table_name(input). How can we do this. Please suggest
Thanks and Regards,
MaheshMahesh Ananth wrote:
Hi All,
I am writing a procedure in PLSQL, based on user input(user will input table name) we have to do a select * from table_name(input). How can we do this. Please suggestThis is generally bad practice so perhaps if you explain what you are trying to achieve in your business we can suggest a better way.
However, if you must..
SQL> ed
Wrote file afiedt.buf
1 create or replace procedure open_rc(p_table IN VARCHAR2, p_rc OUT sys_refcursor) is
2 begin
3 open p_rc for 'select * from '||p_table;
4* end;
SQL> /
Procedure created.
SQL> var x refcursor
SQL> exec open_rc('emp',:x);
PL/SQL procedure successfully completed.
SQL> print x;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7369 SMITH CLERK 7902 17-DEC-80 800 20
7499 ALLEN SALESMAN 7698 20-FEB-81 1600 300 30
7521 WARD SALESMAN 7698 22-FEB-81 1250 500 30
7566 JONES MANAGER 7839 02-APR-81 2975 20
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30
7698 BLAKE MANAGER 7839 01-MAY-81 2850 30
7782 CLARK MANAGER 7839 09-JUN-81 2450 10
7788 SCOTT ANALYST 7566 19-APR-87 3000 20
7839 KING PRESIDENT 17-NOV-81 5000 10
7844 TURNER SALESMAN 7698 08-SEP-81 1500 0 30
7876 ADAMS CLERK 7788 23-MAY-87 1100 20
7900 JAMES CLERK 7698 03-DEC-81 950 30
7902 FORD ANALYST 7566 03-DEC-81 3000 20
7934 MILLER CLERK 7782 23-JAN-82 1300 10
14 rows selected.
SQL> exec open_rc('dept',:x);
PL/SQL procedure successfully completed.
SQL> print x;
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL> -
Plsql use a function which returns a ref cursor
Hi
I've been using an function which returns a ref cursor. I've been returning this into a java resultset. Fine!
Now i'm in plsql and want to use the same function. I'm not sure how to get this resultset in plsql.It's not very practical to use a refcursor like you want to, but here you go
create or replace function test_ref
return sys_refcursor
is
v_rc sys_refcursor;
begin
open v_rc for select emp_name from emp ;
return v_rc;
end;
declare
v_rc sys_refcursor;
v_emp_name emp.emp_name%type;
begin
v_rc := test_ref ;
loop
fetch v_rc into v_emp_name ;
exit when v_rc%notfound ;
dbms_output.put_line('Employee Name: '||v_emp_name );
end loop;
end; -
Hi All,
I have a database with about 500 tables, which can be divided into 100 sets. Each set has 5 tables. There are certain parent-child relationship within the set. All of the 100 sets have the identical logic. However the non-key fields are different. Any suggestion on how to design my PLSQL procedure and function?
Thanks,
Mikeuser550903 wrote:
All the tables are in the same schema. I know it is a bad design from schema point of view. However, it is there already, and I have no right to modify it. All I want to do is to foger out a good solution for PLSQL. Actually, I am able to use dynamic SQL to handle different operations on different tables based on Oracle system table. But, I don't know how I can pass the augment for different row type, and how can I call different function bases on the table name. If you are formilar to C++, all I want is similar to template and pointer to a function.
Thanks in advance.Well, the moment you get into dynamic SQL you start having to write more complex code and sometimes dynamic PL/SQL, which is a nightmare to debug and maintain and doesn't allow for validation at compile time, but can lead to bugs becoming apparent at run time, and sometimes only with certain data or situations. It's buggy and doesn't scale well.
Because you want it "generic" you are saying that you don't want to hard code the individual table structures, and when you come to do that you have to get into the bowels of SQL and use something like the DBMS_SQL package to build your queries and bind parameters and then process the results based on column position rather than column name, looking at the definition of each column to determine the column type and then handling each type on-the-fly.
Such code can have it's uses, such as one I wrote for my own purposes to quickly export data from queries as CSV files. The following code gives an example of that (it's limited to just specifically handling numbers, varchar2's and dates, but could be expanded upon)...
As sys user:
CREATE OR REPLACE DIRECTORY TEST_DIR AS '\tmp\myfiles'
GRANT READ, WRITE ON DIRECTORY TEST_DIR TO myuser
/As myuser:
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2
,p_dir IN VARCHAR2
,p_header_file IN VARCHAR2
,p_data_file IN VARCHAR2 := NULL) IS
v_finaltxt VARCHAR2(4000);
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_fh UTL_FILE.FILE_TYPE;
v_samefile BOOLEAN := (NVL(p_data_file,p_header_file) = p_header_file);
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
END CASE;
END LOOP;
-- This part outputs the HEADER
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_header_file,'w',32767);
FOR j in 1..col_cnt
LOOP
v_finaltxt := ltrim(v_finaltxt||','||lower(rec_tab(j).col_name),',');
END LOOP;
-- DBMS_OUTPUT.PUT_LINE(v_finaltxt);
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
IF NOT v_samefile THEN
UTL_FILE.FCLOSE(v_fh);
END IF;
-- This part outputs the DATA
IF NOT v_samefile THEN
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_data_file,'w',32767);
END IF;
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(c);
EXIT WHEN v_ret = 0;
v_finaltxt := NULL;
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
v_finaltxt := ltrim(v_finaltxt||','||v_n_val,',');
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
v_finaltxt := ltrim(v_finaltxt||','||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),',');
ELSE
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
END CASE;
END LOOP;
-- DBMS_OUTPUT.PUT_LINE(v_finaltxt);
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
END LOOP;
UTL_FILE.FCLOSE(v_fh);
DBMS_SQL.CLOSE_CURSOR(c);
END;This allows for the header row and the data to be written to seperate files if required.
e.g.
SQL> exec run_query('select * from emp','TEST_DIR','output.txt');
PL/SQL procedure successfully completed.Output.txt file contains:
empno,ename,job,mgr,hiredate,sal,comm,deptno
7369,"SMITH","CLERK",7902,17/12/1980 00:00:00,800,,20
7499,"ALLEN","SALESMAN",7698,20/02/1981 00:00:00,1600,300,30
7521,"WARD","SALESMAN",7698,22/02/1981 00:00:00,1250,500,30
7566,"JONES","MANAGER",7839,02/04/1981 00:00:00,2975,,20
7654,"MARTIN","SALESMAN",7698,28/09/1981 00:00:00,1250,1400,30
7698,"BLAKE","MANAGER",7839,01/05/1981 00:00:00,2850,,30
7782,"CLARK","MANAGER",7839,09/06/1981 00:00:00,2450,,10
7788,"SCOTT","ANALYST",7566,19/04/1987 00:00:00,3000,,20
7839,"KING","PRESIDENT",,17/11/1981 00:00:00,5000,,10
7844,"TURNER","SALESMAN",7698,08/09/1981 00:00:00,1500,0,30
7876,"ADAMS","CLERK",7788,23/05/1987 00:00:00,1100,,20
7900,"JAMES","CLERK",7698,03/12/1981 00:00:00,950,,30
7902,"FORD","ANALYST",7566,03/12/1981 00:00:00,3000,,20
7934,"MILLER","CLERK",7782,23/01/1982 00:00:00,1300,,10The procedure allows for the header and data to go to seperate files if required. Just specifying the "header" filename will put the header and data in the one file.
Adapt to output different datatypes and styles are required.
===========================================================================================================================
FIXED WIDTH FORMAT
===========================================================================================================================
As sys user:
CREATE OR REPLACE DIRECTORY TEST_DIR AS '\tmp\myfiles'
GRANT READ, WRITE ON DIRECTORY TEST_DIR TO myuser
/As myuser:
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2
,p_dir IN VARCHAR2
,p_header_file IN VARCHAR2
,p_data_file IN VARCHAR2 := NULL) IS
v_finaltxt VARCHAR2(4000);
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
v_fh UTL_FILE.FILE_TYPE;
v_samefile BOOLEAN := (NVL(p_data_file,p_header_file) = p_header_file);
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
END CASE;
END LOOP;
-- This part outputs the HEADER
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_header_file,'w',32767);
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN v_finaltxt := v_finaltxt||rpad(lower(rec_tab(j).col_name),rec_tab(j).col_max_len,' ');
WHEN 2 THEN v_finaltxt := v_finaltxt||rpad(lower(rec_tab(j).col_name),rec_tab(j).col_max_len,' ');
WHEN 12 THEN v_finaltxt := v_finaltxt||rpad(lower(rec_tab(j).col_name),greatest(19,length(rec_tab(j).col_name)),' ');
END CASE;
END LOOP;
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
IF NOT v_samefile THEN
UTL_FILE.FCLOSE(v_fh);
END IF;
-- This part outputs the DATA
IF NOT v_samefile THEN
v_fh := UTL_FILE.FOPEN(upper(p_dir),p_data_file,'w',32767);
END IF;
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(c);
EXIT WHEN v_ret = 0;
v_finaltxt := NULL;
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
v_finaltxt := v_finaltxt||rpad(nvl(v_v_val,' '),rec_tab(j).col_max_len,' ');
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
v_finaltxt := v_finaltxt||rpad(nvl(to_char(v_n_val,'fm99999999999999999999999999999999999999'),' '),rec_tab(j).col_max_len,' ');
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
v_finaltxt := v_finaltxt||rpad(nvl(to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),' '),greatest(19,length(rec_tab(j).col_name)),' ');
END CASE;
END LOOP;
UTL_FILE.PUT_LINE(v_fh, v_finaltxt);
END LOOP;
UTL_FILE.FCLOSE(v_fh);
DBMS_SQL.CLOSE_CURSOR(c);
END;This allows for the header row and the data to be written to seperate files if required.
e.g.
SQL> exec run_query('select * from emp','TEST_DIR','output.txt');
PL/SQL procedure successfully completed.Output.csv file contains:
empno ename job mgr hiredate sal comm deptno
7369 SMITH CLERK 7902 17/12/1980 00:00:00800 20
7499 ALLEN SALESMAN 7698 20/02/1981 00:00:001600 300 30
7521 WARD SALESMAN 7698 22/02/1981 00:00:001250 500 30
7566 JONES MANAGER 7839 02/04/1981 00:00:002975 20
7654 MARTIN SALESMAN 7698 28/09/1981 00:00:001250 1400 30
7698 BLAKE MANAGER 7839 01/05/1981 00:00:002850 30
7782 CLARK MANAGER 7839 09/06/1981 00:00:002450 10
7788 SCOTT ANALYST 7566 19/04/1987 00:00:003000 20
7839 KING PRESIDENT 17/11/1981 00:00:005000 10
7844 TURNER SALESMAN 7698 08/09/1981 00:00:001500 0 30
7876 ADAMS CLERK 7788 23/05/1987 00:00:001100 20
7900 JAMES CLERK 7698 03/12/1981 00:00:00950 30
7902 FORD ANALYST 7566 03/12/1981 00:00:003000 20
7934 MILLER CLERK 7782 23/01/1982 00:00:001300 10
The procedure allows for the header and data to go to seperate files if required. Just specifying the "header" filename will put the header and data in the one file.
As you can see, the query has to be parsed and executed by the code and then we can use the Describe functionality to get the DBMS_SQL package to tell us what the results look like, but then we have to handle each type of column based on it's internal datatype number (details can be found on the internet or in the documentation).
So, you can write PL/SQL code to query your tables "generically", but if you want to somehow define a structure to pass back to a 3rd party language, you are actually going to have to look at using Ref Cursors, and then the 3rd party application has to do what I was showing in the example code above, which is to describe the results and process the columns based on position etc. A lot of 3rd party software does this automatically with ref cursors.
Simple example of a Ref Cursor:
SQL> CREATE OR REPLACE PACKAGE reftest IS
2 PROCEDURE test(P_no in number, cur_o OUT sys_refcursor);
3 end;
4 /
Package created.
SQL>
SQL> CREATE OR REPLACE PACKAGE body reftest as
2 PROCEDURE test(P_no in number, cur_o OUT sys_refcursor) as
3 myexc exception;
4 BEGIN
5 if P_no = 1 then
6 open cur_o for select empno, ename from emp;
7 elsif p_no =2 then
8 open cur_o for select deptno, dname from dept;
9 else
10 RAISE myexc;
11 END IF;
12 exception
13 when myexc then
14 raise_application_error(20991,'input must be 1 or 2');
15 end ;
16 end reftest;
17 /
Package body created.
SQL> var x refcursor;
SQL> exec reftest.test(1,:x);
PL/SQL procedure successfully completed.
SQL> print x;
EMPNO ENAME
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
14 rows selected.
SQL> exec reftest.test(2,:x);
PL/SQL procedure successfully completed.
SQL> print x;
DEPTNO DNAME
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
SQL>Here, it may not be that obvious, but the SQL*Plus client tool obtains the ref cursor back from the procedure and then it is actually SQL*Plus that has to describe the cursor and determine how it will display the results based on the datatypes of the returned columns. The PL/SQL code hasn't had to concern itself with passing back any description except what is in-built to the ref cursor itself.
In reality the same thing happens when you just execute an SQL query in SQL*Plus, as SQL*Plus has to do the process of opening a cursor for the SQL statmeent, requesting a parse of the query, getting a description of the results, fetching the data back row by row and then displaying the results based on the description. However, that's all hidden from you. -
Hi i am new to plsql
i am trying to execute a simple program using labels,but its throwing error
program :
<<label1>>
declare
x varchar2(10) := 'hello';
begin
declare
x varchar2(10) := 'there';
begin
dbms_output.put_line(label1.x || x);
end;
end label1;
Error:
<<label1>>
declare
x varchar2(10) := 'hello'
ORA-06550: line 5, column 0:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
8 /
begin
declare
x varchar2(10) := 'there';
begin
dbms_output.put_line(label1.x || x);
end;
end label1;
ORA-06550: line 5, column 33:
PLS-00201: identifier 'LABEL1.X' must be declared
ORA-06550: line 5, column 12:
PL/SQL: Statement ignored
it is working fine.if i wont use label in this program.
someone please help me out to resolve this problem..986127 wrote:
jus wanna know labelling concepts, so tried with basic exampleI've never used it in many years of PL/SQL programming.
Labelling, I think, comes from writing spaghetti code - nested blocks, using goto statements, etc.
What labelling does show though, is the importance of explicit scope. When you have object name collisions (same name used by different code blocks/objects), you need to rather explicitly specify the scope, than leave it for the compiler to figure it out (and potentially incorrectly).
However, actual labels are not needed. Simplistic example. Table object uses empno as column name and stored proc uses empno as variable name:
SQL> create or replace procedure GetEmployee( c out sys_refcursor, empno emp.empno%Type ) is
2 begin
3 --// uses explicit scope to distinguish between empno as column and
4 --// empno as parameter
5 open c for
6 select
7 e.*
8 from emp e
9 where e.empno = GetEmployee.empno;
10 end;
11 /
Procedure created.
SQL>
SQL> var c refcursor
SQL> exec GetEmployee( :c, 7902 );
PL/SQL procedure successfully completed.
SQL> print c
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
7902 FORD ANALYST 7566 1981/12/03 00:00:00 3000 20
SQL> There is a somewhat misguided standard used in PL/SQL, based on (outdated and flawed) Hungarian notation, that states that parameters need to be prefixed using "+p_+" and variables using "+v_+".
But is a superfluous standard. The PL/SQL language supports explicit scope resolution. There's no reason to reinvent that, and reinvent it poorly and inconsistently, using a Hungarian notation style standard. -
I'm in a PLSQL loop and I need to do a spool for a select statement. This doesn't work because within plsql, it needs a select Into clause. Is there anyway of sending the output to a file?
Use REF CURSOR as out parameter of the procedure. Open the ref cursor for a query inside the procedure.
SQL> var x REFCURSOR
SQL> exec proc1(:x);
SQL> print x -
How to link a non-linkable query and a plsql query in the datamodel
Hi,
I am creating a matrix group....
Where in I get my
1) Column values from a non-linkable query - Period (Jan, Feb....)
2) Row values from a plsql query (ref cursor). Group is also from this query
3) Cross product is on the above two queries.
4) Cell info comes from a plsql query (refcursor).
I created a group link from the cross product group (3) to the cell info query (4)
I prepared the layout and executed the report... I am getting redundant data....
The reason being the (4) and (1) are not linked properly.
From google, About non-linkable queries column.... I understood that to link two non-linkable queries, we need to create a group link and then add a where clause in the child query referring the parent query column.
But my case is a non-linkable query (which is a parent ) and a plsql query which is the cell.
Any help...?
Thanks in advance.
KKHello Sam,
>
I was wondering if you could have any link or examples to show how to make a form with report and an insert form in the same page, these two forms are related to the same table. Our customer wants a user can add new row to the table in a form and see all of rows created by this user in a report, this report should provide edit link as well. the problem is: whenever I inserted a new row or edit a row or delete a row, and submitted, and return to this page, all of hidden items lost their values, so report is blank, and some display only items also lost their values. Could anyone give me suggestions?
>
This will help:
http://www.grassroots-oracle.com/2011/09/apex-tutorial-form-report-sharing-same.html
Hope it helps!
Regards,
Kiran -
Error while trying to access a SSWA PLSQL function
Hi,
I am trying to access a report as a web page by defining the function as follows :
Type : SSWA PLSQL FUNCTION
HTML Call : OracleOASIS.RunReport
Parameters : report=EMPDET
This function is attached to the menu and when I try to access the page I get this error.
"Error: The requested URL was not found, or cannot be served at this time.
Incorrect usage."
The URL that shows in the page is as follows(<server:port> I removed the server name and port) :
http://<server:port>/dev60cgi/rwcgi60?GDEV_APPS+DESFORMAT=HTML+SERVER=GDEV_APPS+report=EMPDET+p_session_id=A9C71A70B9B1D9BD2DCC0FC3AF9BC324+p_user_id=1133+p_responsibility_id=50230+p_application_id=800+p_security_group_id=0+p_language_code=US+NLS_LANG=AMERICAN_AMERICA+NLS_DATE_FORMAT=DD-MON-RRRR+NLS_NUMERIC_CHARACTERS=.%2C+NLS_DATE_LANGUAGE=AMERICAN+NLS_SORT=BINARY+paramform=NO
Surprisingly other functions which are defined in this manner work fine. Do I need to register my report anywhere or are there any other settings I need to do for the report to show up.
Can someone let me know.
ThanksHi ;
pelase check below which could be similar error like yours
Troubleshooting of Runtime Errors of Customer Intelligence Reports [ID 284829.1]
Regard
Helios
Maybe you are looking for
-
WHERE IS ADOBE INCOPY????
I am trying to download inCopy as a trial before purchasing. I click the Download Now button to downoad Adobe Download Assistant. I install ADA on my desktop. When it opens, I login. THEN WHAT? Nothing happens. No downloads. I search through all of t
-
Hey guys, HELP!! I can't figure out why I get a blinking effect (when I say blinking, it might blink 2-3 frames of black throughout a 60 second sequence)when I try to export my alpha channel animation sequence. It plays back just fine in FCP until I
-
How to show speed, when only using maps
Hi I have a 5230, I will like to see the speed I am driving, only using map, but no destianation, is that posible and how. Br/
-
How Do I Import Outlook Express Address Book?
I have a PC running WXP using Outlook Express as a mail client. And, I have a MAC that I'm trying to get email set up on. I'm trying to get completely off WXP as a home computing environment. Accordingly, I'd like to import the Outlook Express addres
-
SpaceX is looking for engineers with LabVIEW experience in Hawthorne CA (LA area)
SpaceX is looking for engineers with LabVIEW programming experience for our Launch group. Our responsibilities include: Controlling launch pad equipment via PXI/LabVIEW Commanding and monitoring our Falcon 1 and Falcon 9 rockets via a LabVIEW-based V