PL/SQL package hasc1 in out cursor variable param.how to exec @ SQL
I have a PL/SQL procedure with 1 in out parameter which is cursor variable. How to execute this procedure on SQL prompt?
My code looks like this:
CREATE OR REPLACE PACKAGE PackFlight AS
TYPE GenCurType is REF CURSOR;
PROCEDURE searchFlight(pdate in flight.flight_date%TYPE,
gen_cursor IN OUT GenCurType);
END PackFlight;
I want to execute this procedure at SQL Prompt? Could you please tell me how to do this?
If I create a stand-alone procedure with ref-cursor, then how to execute this @ SQL Prompt?
Thanks a lot,
Supriya
var rc refcursor
exec packflight.searchflight (sysdate, :rc);
Similar Messages
-
Migration Workbench Ver 1.2.2 has migrated an SQL Server 6.5
strored procedure as a package containing only the Cursor
variable and a procedure with INOUT parameter with packaged
cusorvariable as one of the parameters to Oracle 8.0.5.
How do you execute this procedure from SQL + and from another
PL/SQL block where you have to retrive the data elements of the
cursor.(ie.How do you input the cursor variable parameter in the
EXECUTE stored procedure command.)An example of the type is
appreciated.
nullSurendra,
Using refcursors between procedures is covered in the 'Wrong
number or types of argument in call to stored proc' 4 jun thread,
with reference to the manuals.
Using refcursor bind variables is covered in the sqlplus user
guide and reference reproduced below (from the 8.1.5 version,
also in 8.0.5) available on line on OTN.
Hope that helps,
Turloch
Oracle Migration Workbench Team
Using REFCURSOR Bind Variables
SQL*Plus REFCURSOR bind variables allow SQL*Plus to fetch and
format the results of a SELECT statement contained in a PL/SQL
block.
REFCURSOR bind variables can also be used to reference PL/SQL
cursor variables in stored procedures. This allows you to store
SELECT statements in the database and reference them from
SQL*Plus.
A REFCURSOR bind variable can also be returned from a stored
function.
Note:
You must have Oracle7, Release 7.3 or above to assign
the return value of a stored function to a
REFCURSOR variable.
Example 3-18 Creating, Referencing, and Displaying REFCURSOR Bind
Variables
To create, reference and display a REFCURSOR bind variable, first
declare a local bind variable of the REFCURSOR datatype
SQL> VARIABLE dept_sel REFCURSOR
Next, enter a PL/SQL block that uses the bind variable in an OPEN
... FOR SELECT statement. This statement opens a cursor variable
and executes a query. See the PL/SQL User's Guide and Reference
for information on the OPEN command and cursor variables.
In this example we are binding the SQL*Plus dept_sel bind
variable to the cursor variable.
SQL> BEGIN
2 OPEN :dept_sel FOR SELECT * FROM DEPT;
3 END;
4 /
PL/SQL procedure successfully completed.
The results from the SELECT statement can now be displayed in
SQL*Plus with the PRINT command.
SQL> PRINT dept_sel
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
The PRINT statement also closes the cursor. To reprint the
results, the PL/SQL block must be executed again before using
PRINT.
Example 3-19 Using REFCURSOR Variables in Stored Procedures
A REFCURSOR bind variable is passed as a parameter to a
procedure. The parameter has a REF CURSOR type. First, define the
type.
SQL> CREATE OR REPLACE PACKAGE cv_types AS
2 TYPE DeptCurTyp is REF CURSOR RETURN dept%ROWTYPE;
3 END cv_types;
4 /
Package created.
Next, create the stored procedure containing an OPEN ... FOR
SELECT statement.
SQL> CREATE OR REPLACE PROCEDURE dept_rpt
2 (dept_cv IN OUT cv_types.DeptCurTyp) AS
3 BEGIN
4 OPEN dept_cv FOR SELECT * FROM DEPT;
5 END;
6 /
Procedure successfully completed.
Execute the procedure with a SQL*Plus bind variable as the
parameter.
SQL> VARIABLE odcv REFCURSOR
SQL> EXECUTE dept_rpt(:odcv)
PL/SQL procedure successfully completed.
Now print the bind variable.
SQL> PRINT odcv
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
The procedure can be executed multiple times using the same or a
different REFCURSOR bind variable.
SQL> VARIABLE pcv REFCURSOR
SQL> EXECUTE dept_rpt(:pcv)
PL/SQL procedure successfully completed.
SQL> PRINT pcv
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
Example 3-20 Using REFCURSOR Variables in Stored Functions
Create a stored function containing an OPEN ... FOR SELECT
statement:
SQL> CREATE OR REPLACE FUNCTION dept_fn RETURN -
cv_types.DeptCurTyp IS2 resultset cv_types.DeptCurTyp;
3 BEGIN
4 OPEN resultset FOR SELECT * FROM DEPT;
5 RETURN(resultset);
6 END;
7 /
Function created.
Execute the function.
SQL> VARIABLE rc REFCURSOR
SQL> EXECUTE :rc := dept_fn
PL/SQL procedure successfully completed.
Now print the bind variable.
SQL> PRINT rc
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
4 rows selected
The function can be executed multiple times using the same or a
different REFCURSOR bind variable.
SQL> EXECUTE :rc := dept_fn
PL/SQL procedure successfully completed.
SQL> PRINT rc
DEPTNO DNAME LOC
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
Surendra Kumar (guest) wrote:
: Migration Workbench Ver 1.2.2 has migrated an SQL Server 6.5
: strored procedure as a package containing only the Cursor
: variable and a procedure with INOUT parameter with packaged
: cusorvariable as one of the parameters to Oracle 8.0.5.
: How do you execute this procedure from SQL + and from
another
: PL/SQL block where you have to retrive the data elements of the
: cursor.(ie.How do you input the cursor variable parameter in
the
: EXECUTE stored procedure command.)An example of the type is
: appreciated.
Oracle Technology Network
http://technet.oracle.com
null -
Is IN OUT for Cursor variable mandatory?
Hi all:
I have a stored procedure which will just return a boolean value after the task is done. And i'm using more than 1 cursor variables in that stored procedure. What my question is
"Is IN OUT for Cursor variable mandatory from the PROCEDURE i have written?".
Because in the manual they mentioned that IN OUT should be there for a cursor variable. My PROCEDURE declaration is as below:
TYPE emp_det IS REF CURSOR;
PROCEDURE <proc_name>(startdate VARCHAR2, enddate VARCHAR2, ids VARCHAR2, taskdone OUT BOOLEAN,emp IN OUT emp_det);
Is there any modification in the above declaration if i'm using one cursor and NOT returning that cursor back to the called program. I don't to get returned.
Hope i made it clear.
Thanks,
- VenuVenu:
As far as I know you don't need In Out unless
you are using that variable to pass values between the two procedures.
It is so easy to try it , so I suggest you write two small procedures to check this.It should only take a couple of minutes.
Hope this helps. -
PL/SQL column names in cursor variable
Hi,
I try to put all column names of a table in a cursor variable?? without the values, just the column names.
Can somebody help me, because I really don't know how to do this.
Thanks,
MoniHi Jes,
my table looks like this: T1
columnNames: id | col1 | col2 | col3 | col4 | col5
Values: a | b | c| d| e| f
the number of the columns depend on a how many rows in another table (T2) are entered. If a new row is entered in T2, I have to add a column in table T1.
and then I have to look what is the new row, compare it with all my existing columnnames in T1 and add the right one.
my vector should look like this:
c1:
id
col1
col2
col3
col4
col5
I hope you know what I mean, it is not very easy to describe!
Thanks for helping me!
Moni -
Cursor Variables in Pro*C/C++
I have very strange behaivour of the client application that uses cursor variable.
I have Oracle 8i enterprise 8.1.6 release for Sun/Solaris.
The follow SQL is installed on server:
create or replace package dummy is
type vemap_cur is ref cursor;
end;
create or replace procedure GET_CUR
( N IN number, cur IN OUT dummy.VEMAP_CUR ) as
begin
open cur for
select LS.ID, LS.SCALE
from LAYERS LS
where LS.ID = (select C.ID from CTM C where C.ORDERINDEX = N);
end;
This procedure (GET_CUR) i call from embedded SQL in follow manner:
EXEC SQL BEGIN DECLARE SECTION;
struct
int n1;
int n2;
} resrec;
sql_cursor c1;
int num;
EXEC SQL END DECLARE SECTION;
EXEC SQL ALLOCATE :c1;
EXEC SQL AT DB_VE EXECUTE
BEGIN
GET_VEC( :num, :c1 );
END;
END-EXEC;
Till now it is Ok. But when i run the follow line
EXEC SQL FETCH :c1 INTO :resrec;
i accept ORA-01012: not logged on
error !!!!
I checked the connection via using cursor in paralell and got the correct answer.
Therefore i think this error is not related to the actual problem and i have no idea what this problem is. I tried to open cursor via anonymous PL/SQL block inside my C program with same result.
Need help ASAP.
Leonid
nullHi Leonid, Andrea
When you use "CONNECT AT :db_handle" instead of default connection "CONNECT", you have to give the connect handle to the command you want to execute.
ie:
EXEC SQL AT :db_handle PREPARE SQL_stat FROM "select ...";
EXEC SQL AT :db_handle DECLARE cur_stat CURSOR for SQL_stat;
EXEC SQL AT :db_handle OPEN cur_stat ;
EXEC SQL AT :db_handle FETCH cur_stat INTO :resrec;
Leonid, the error you had is probably because you connected at "DB_VE", and tried to select from default connect (that you're not connected to ==> ORA-01012)
Try EXEC SQL AT :DB_VE FETCH :c1 INTO :resrec;
or, if you connect to only 1 database, use "EXEC SQL CONNECT;" instead of (EXEC SQL CONNECT :pConnectString AT "DB_VE";) so that you use default connect name and you don't have to add "AT :DB_VE" to your SQL commands.
I know this reply comes long after your request, but I hope it may still help anybody. -
How to (in Pro*C) pass a cursor variable as a pointer between functions
I am opening a cursor in a called function that accepts as one argument a pointer to a cursor variable, and a second argument for the sql string defining the cursor select. That works fine, and in that same function can successfully fetch and access the records from the cursor. However, my objective is to fetch the records in another function that calls the first function. I want to pass back to the calling function the pointer to the cursor variable from the first function. In the second (calling) function, is where I want to fetch the records. What I am getting is SQLCODE = -1002 (fetch out of sequence).
Here is the relevent code in the first called function that calls a PL/SQL package procedure to open the cursor, followed by the code in the second calling procedure where I am attempting to fetch the records:
/******Called function code starts here ******/
EXEC SQL INCLUDE SQLCA;
long db_makeCursor(cursorID, SQLstr)
EXEC SQL BEGIN DECLARE SECTION;
sql_cursor cursorID; / a pointer to a cursor variable */
char *SQLstr;
EXEC SQL END DECLARE SECTION;
long SQLCODE;
EXEC SQL BEGIN DECLARE SECTION;
sql_cursor dbCursor; /* a cursor variable */
EXEC SQL END DECLARE SECTION;
EXEC SQL WHENEVER SQLERROR DO sql_error();
dbCursor = *cursorID;
EXEC SQL EXECUTE
BEGIN
db_util_ref_cursor_pkg.open_dbNameCursor( :dbCursor, :SQLstr );
END;
END-EXEC;
return;
/******Calling function code starts here ******/
EXEC SQL INCLUDE SQLCA;
EXEC SQL BEGIN DECLARE SECTION;
static PROCLOG PROC_Rec;
EXEC SQL END DECLARE SECTION;
long retrieveProcesses( _proclog, sqlForProcLog )
EXEC SQL BEGIN DECLARE SECTION;
PROCLOG _proclog;
char *sqlForProcLog
EXEC SQL END DECLARE SECTION;
long rc;
long SQLCODE;
EXEC SQL BEGIN DECLARE SECTION;
sql_cursor dbCursor; /* a cursor variable */
sql_cursor cursorID; / a pointer to a cursor variable */
PROCLOG proclog;
short end_ts_ind;
short proc_name_ind;
short comments_ind;
EXEC SQL END DECLARE SECTION;
cursorID = &dbCursorName; /* assign a value to the pointer */
EXEC SQL ALLOCATE :dbCursor;
rc = dbUtilities_makeCursor( cursorID, sqlForProcLog);
if (rc == TRUE)
while (SQLCODE == 0)
EXEC SQL FETCH :dbCursorName INTO
:proclog.PROC_ID,
:proclog.START_TS,
:proclog.END_TS:end_ts_ind,
:proclog.PROC_NAME:proc_name_ind,
:proclog.COMMENTS:comments_ind,
if (SQLCODE == 0)
printf("PROC_ID: %d; COMMENTS: %s\n",proclog.PROC_ID, proclog.COMMENTS);
} /* end retrieveProcesses */You need to include a loop...
for i=0;i<sqlca.sqlerrd[2];i++)
printf("name %s\n", struct.name)
This allows you to step through your cursor records!!! -
Cursor variable persistence (or lack of) - workarounds ?
Using 11.1.0.7; want to be able to pass a query SQL statement out of a client to a database package and have the package execute the query and return N rows out of the query, and later serve requests from client for the next N records etc. Having opened the cursor I then want to be able to retain a reference to it for the secondary / subsequent look-ups. The restrictions on package cursor variable definition prevent the obvious solution(s). Wondering whether others had experience of delivering such a solution ?
Have trialled use of DBMS_SQL, but under 11g run into restrictions relating to new 11g security features, which the docco suggests can be disabled, but reluctant to do so. Returning the cursor reference to client (Oracle Forms) could be the next option, but would prefer to not. Figured this might've already been solved ...?
Thanks,robli wrote:
I can pass the ref cursor back to the client but there's no way to otherwise persist the ref cursor in the database session - true ?Yes you can persist ref cursors in 11g:
SQL> --// custom data type for storing DBMS_SQL cursor handles
SQL> create or replace type TCursorList is table of number;
2 /
Type created.
SQL> --// our interface for storing (persisting) ref cursor handles in PL/SQ:
SQL> create or replace package CursorContainer as
2 --// store a ref cursor (and get an index number in return to
3 --// access that ref cursor again)
4 procedure StoreRefCursor( c in out sys_refcursor, idx out number );
5
6 --// retrieve a stored ref cursor handle
7 function GetRefCursor( idx number ) return sys_refcursor;
8
9 function CursorList return TCursorList;
10 end;
11 /
Package created.
SQL>
SQL> create or replace package body CursorContainer as
2 --// actual variable/collection that contains the handles
3 cursors TCursorList;
4
5 procedure StoreRefCursor( c in out sys_refcursor, idx out number ) is
6 begin
7 if cursors is null then
8 cursors := new TCursorList();
9 end if;
10
11 cursors.Extend(1);
12 cursors( cursors.Count ) := DBMS_SQL.To_Cursor_Number( c );
13
14 idx := cursors.Count;
15 end;
16
17 function GetRefCursor( idx number ) return sys_refcursor is
18 begin
19 return(
20 DBMS_SQL.To_RefCursor(
21 cursors( idx )
22 )
23 );
24 end;
25
26 function CursorList return TCursorList is
27 begin
28 return( cursors );
29 end;
30
31 end;
32 /
Package body created.
SQL>
SQL> --// create and store 2 ref cursors
SQL> declare
2 c1 sys_refcursor;
3 c2 sys_refcursor;
4 n number;
5 begin
6 open c1 for select sysdate from dual;
7 open c2 for select rownum, d.dummy from dual d;
8
9 CursorContainer.StoreRefCursor( c1, n );
10 CursorContainer.StoreRefCursor( c2, n );
11 end;
12 /
PL/SQL procedure successfully completed.
SQL>
SQL> --// what handles did we store?
SQL> select column_value as CURSOR_HANDLE from TABLE(CursorContainer.CursorList);
CURSOR_HANDLE
388610362
54290194
SQL>
SQL> --// we define a ref cursor pointer on the client side
SQL> var c refcursor
SQL> --// okay, we now consume these stored ref cursor handles
SQL> --// grab cursor 1, consume and close it
SQL> exec :c := CursorContainer.GetRefCursor(1);
PL/SQL procedure successfully completed.
SQL> print :c
SYSDATE
2011-03-02 13:56:22
SQL>
SQL> --// grab cursor 2, consume and close it
SQL> exec :c := CursorContainer.GetRefCursor(2);
PL/SQL procedure successfully completed.
SQL> print :c
ROWNUM DUM
1 X
SQL> I would however question such an interface for storing ref cursor handles... I have never in many years of Oracle client-server and PL/SQL development, ran into the requirement to persist ref cursor handles in PL/SQL(either for later consumption in PL/SQL, or consumption by an external client).
The approach does not sound very robust to me. -
Cursor Variable in Nested Block
Dear all,
I have a package that has procedures that open cursor variables and print the queries of sample schema HR. There's one procedure that opens the cursor with an input integer to choose which query that wants to be fetched. The other prints the query by fetching the cursor in a nested block with exceptions. The following package runs as intended, it prints all the three options without any problems:
CREATE OR REPLACE PACKAGE admin_data AS
TYPE gencurtyp IS REF CURSOR;
PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT);
procedure print_cv (generic_cv gencurtyp);
END admin_data;
CREATE OR REPLACE PACKAGE BODY admin_data AS
PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT) IS
BEGIN
IF choice = 1 THEN
OPEN generic_cv FOR SELECT * FROM jobs where job_id='ST_MAN';
ELSIF choice = 2 THEN
OPEN generic_cv FOR SELECT * FROM departments where department_id=270;
ELSIF choice = 3 THEN
OPEN generic_cv FOR SELECT * FROM employees where employee_id=206;
END IF;
END;
procedure print_cv (generic_cv gencurtyp)is
employees_rec employees%rowtype;
departments_rec departments%rowtype;
jobs_rec jobs%rowtype;
begin
fetch generic_cv into jobs_rec;
dbms_output.put_line(jobs_rec.job_title);
exception
when ROWTYPE_MISMATCH then
begin
fetch generic_cv into departments_rec;
dbms_output.put_line(departments_rec.department_name);
exception
when ROWTYPE_MISMATCH then
dbms_output.put_line('row mismatch');
fetch generic_cv into employees_rec;
dbms_output.put_line(employees_rec.first_name);
when OTHERS then
dbms_output.put_line('others');
fetch generic_cv into employees_rec;
dbms_output.put_line(employees_rec.first_name);
end;
end print_cv;
END admin_data;
declare
some_cur admin_data.gencurtyp;
begin
admin_data.open_cv(some_cur,1);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,2);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,3);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,3);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,1);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,2);
admin_data.print_cv(some_cur);
end;
17 /
Stock Manager
Payroll
row mismatch
William
row mismatch
William
Stock Manager
Payroll
PL/SQL procedure successfully completed.The innermost block executes 'rowtype mismatch' exception block, which fetches
SELECT * FROM employees where employee_id=206 query.
This time, I switch the query fetch so that
SELECT * FROM employees where employee_id=206query is in the outermost block and
SELECT * FROM jobs where job_id='ST_MAN' is in the innermost block. The package body looks like this:
CREATE OR REPLACE PACKAGE BODY admin_data AS
PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT) IS
BEGIN
IF choice = 1 THEN
OPEN generic_cv FOR SELECT * FROM jobs where job_id='ST_MAN';
ELSIF choice = 2 THEN
OPEN generic_cv FOR SELECT * FROM departments where department_id=270;
ELSIF choice = 3 THEN
OPEN generic_cv FOR SELECT * FROM employees where employee_id=206;
END IF;
END;
procedure print_cv (generic_cv gencurtyp)is
employees_rec employees%rowtype;
departments_rec departments%rowtype;
jobs_rec jobs%rowtype;
begin
fetch generic_cv into employees_rec;
dbms_output.put_line(employees_rec.first_name);
exception
when ROWTYPE_MISMATCH then
begin
fetch generic_cv into departments_rec;
dbms_output.put_line(departments_rec.department_name);
exception
when ROWTYPE_MISMATCH then
dbms_output.put_line('row mismatch');
fetch generic_cv into jobs_rec;
dbms_output.put_line(jobs_rec.job_title);
when OTHERS then
dbms_output.put_line('others');
fetch generic_cv into jobs_rec;
dbms_output.put_line(jobs_rec.job_title);
end;
end print_cv;
END admin_data;
then I run the same anonymous block, I get:declare
some_cur admin_data.gencurtyp;
begin
admin_data.open_cv(some_cur,1);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,2);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,3);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,3);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,1);
admin_data.print_cv(some_cur);
admin_data.open_cv(some_cur,2);
admin_data.print_cv(some_cur);
end;
17 /
others
Payroll
William
William
others
Payroll
PL/SQL procedure successfully completed.
The strangest thing is the innermost block execute OTHERS exception block instead of ROWTYPE MISMATCH and the the record doesn't fetch anything. What happen? How come the result is different when I only switch the query?
Best regards,
ValHi Sy,
thanks for the reply, yes I agree that the code is cumbersome, I'm studying to prepare OCP PL/SQL certification, so I'm playing around with cursor variable in order to grasp the whole concept. I'm observing the behaviour of weak cursor variable when getting passed into a function and fetched couple of times and exploring exception propagation in the same time. This why the code looks not relevant in the real world.
Anyway, I just curious how it behaves like that. Here's my instance info:
SQL> select * from v$version
2 ;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production -
ORA-4068 Existing stage of package discarded - Techniques of avoid variable
Hi all,
I need to ‘strip’ the state from a package (let’s say PKG_MAIN). I’ve already transform all constants into functions but I have difficulties in finding the best solution for the variables. Most of the variables are collections and I cannot use temporary tables to replace them (performance issues). As well I have tried creating a package (PKG_VARIABLES) for all variables but, as you probably know, this is not a ‘fix’ because changing the PKG_VARIABLES will trigger, when calling the PKG_MAIN, the ORA-4068 anyway.
Any ideas??
Cheers,
Harada[standard response for package state]
Packages tend to fail because of their "package state". A package has a "state" when it contains package level variables/constants etc. and the package is called. Upon first calling the package, the "state" is created in memory to hold the values of those variables etc. If an object that the package depends upon e.g. a table is altered in some way e.g. dropped and recreated, then because of the database dependencies, the package takes on an INVALID status. When you next make a call to the package, Oracle looks at the status and sees that it is invalid, then determines that the package has a "state". Because something has altered that the package depended upon, the state is taken as being out of date and is discarded, thus causing the "Package state has been discarded" error message.
If a package does not have package level variables etc. i.e. the "state" then, taking the same example above, the package takes on an INVALID status, but when you next make a call to the package, Oracle sees it as Invalid, but knows that there is no "state" attached to it, and so is able to recompile the package automatically and then carry on execution without causing any error messages. The only exception here is if the thing that the package was dependant on has changes in such a way that the package cannot compile, in which case you'll get an Invalid package type of error.
And if you want to know how to prevent discarded package states....
Move all constants and variables into a stand-alone package spec and reference those from your initial package. Thus when the status of your original package is invlidated for whatever reason, it has no package state and can be recompiled automatically, however the package containing the vars/const will not become invalidated as it has no dependencies, so the state that is in memory for that package will remain and can continue to be used.
As for having package level cursors, you'll need to make these local to the procedures/functions using them as you won't be able to reference cursors across packages like that (not sure about using REF CURSORS though.... there's one for me to investigate!)
This first example shows the package state being invalided by the addition of a new column on the table, and causing it to give a "Package state discarded" error...
SQL> set serveroutput on
SQL>
SQL> create table dependonme (x number)
2 /
Table created.
SQL>
SQL> insert into dependonme values (5)
2 /
1 row created.
SQL>
SQL> create or replace package mypkg is
2 procedure myproc;
3 end mypkg;
4 /
Package created.
SQL>
SQL> create or replace package body mypkg is
2 v_statevar number := 5; -- this means my package has a state
3
4 procedure myproc is
5 myval number;
6 begin
7 select x
8 into myval
9 from dependonme;
10
11 myval := myval * v_statevar;
12 DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
13 end;
14 end mypkg;
15 /
Package body created.
SQL>
SQL> exec mypkg.myproc
My Result is: 25
PL/SQL procedure successfully completed.
SQL>
SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
2 /
OBJECT_NAME
OBJECT_TYPE STATUS
MYPKG
PACKAGE VALID
MYPKG
PACKAGE BODY VALID
SQL>
SQL>
SQL> alter table dependonme add (y number)
2 /
Table altered.
SQL>
SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
2 /
OBJECT_NAME
OBJECT_TYPE STATUS
MYPKG
PACKAGE VALID
MYPKG
PACKAGE BODY INVALID
SQL>
SQL> exec mypkg.myproc
BEGIN mypkg.myproc; END;
ERROR at line 1:
ORA-04068: existing state of packages has been discarded
ORA-04061: existing state of package body "SCOTT.MYPKG" has been invalidated
ORA-06508: PL/SQL: could not find program unit being called: "SCOTT.MYPKG"
ORA-06512: at line 1
SQL>
SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
2 /
OBJECT_NAME
OBJECT_TYPE STATUS
MYPKG
PACKAGE VALID
MYPKG
PACKAGE BODY INVALID
SQL>
SQL> exec mypkg.myproc
PL/SQL procedure successfully completed.
SQL>
SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
2 /
OBJECT_NAME
OBJECT_TYPE STATUS
MYPKG
PACKAGE VALID
MYPKG
PACKAGE BODY VALIDAnd this next example shows how having the package variables in their own package spec, allows the package to automatically recompile when it is called even though it became invalidated by the action of adding a column to the table.
SQL> drop table dependonme
2 /
Table dropped.
SQL>
SQL> drop package mypkg
2 /
Package dropped.
SQL>
SQL> set serveroutput on
SQL>
SQL> create table dependonme (x number)
2 /
Table created.
SQL>
SQL> insert into dependonme values (5)
2 /
1 row created.
SQL>
SQL> create or replace package mypkg is
2 procedure myproc;
3 end mypkg;
4 /
Package created.
SQL>
SQL> create or replace package mypkg_state is
2 v_statevar number := 5; -- package state in seperate package spec
3 end mypkg_state;
4 /
Package created.
SQL>
SQL> create or replace package body mypkg is
2 -- this package has no state area
3
4 procedure myproc is
5 myval number;
6 begin
7 select x
8 into myval
9 from dependonme;
10
11 myval := myval * mypkg_state.v_statevar; -- note: references the mypkg_state package
12 DBMS_OUTPUT.PUT_LINE('My Result is: '||myval);
13 end;
14 end mypkg;
15 /
Package body created.
SQL>
SQL> exec mypkg.myproc
My Result is: 25
PL/SQL procedure successfully completed.
SQL>
SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
2 /
OBJECT_NAME
OBJECT_TYPE STATUS
MYPKG
PACKAGE VALID
MYPKG
PACKAGE BODY VALID
SQL>
SQL> alter table dependonme add (y number)
2 /
Table altered.
SQL>
SQL> select object_name, object_type, status from user_objects where object_name = 'MYPKG'
2 /
OBJECT_NAME
OBJECT_TYPE STATUS
MYPKG
PACKAGE VALID
MYPKG
PACKAGE BODY INVALID
SQL>
SQL> exec mypkg.myproc
My Result is: 25
PL/SQL procedure successfully completed. -
Getting error in cursor variable in CallableStatement
Hi,
I am trying to retrieve result set from PL/SQL procedure using cursor variable.
but I getting error sometime.
this is code in my program...
CallableStatement pstmt=null;
pstmt = con.prepareCall("{call Crms2.SearchRNameTime(?,?,?,?,?,?)}");
pstmt.setString(1, uid);
pstmt.setString(2, strBookingDate);
pstmt.setInt(3, roomid);
pstmt.setInt(4, lngStartTime);
pstmt.setInt(5, lngEndTime);
pstmt.registerOutParameter(6, oracle.jdbc.driver.OracleTypes.CURSOR ); // error accured in this line
pstmt.execute();
rs = (ResultSet)pstmt.getObject(6);
error was accrued at line : pstmt.registerOutParameter(6, oracle.jdbc.driver.OracleTypes.CURSOR );
error is: orable.jdbc.driver can not resolve tha symbol..
but it some time executing , some time giving error.
it is require any package to import?
please help me on this problem.
regards
Narru990187 wrote:
i have created a cursor to return only 5th row from a table .
declare
cursor cur is select * From(select last_name,salary,rownum rn from employees where rownum<=50)) where rn=5;
just a side note, (others have helped with the actual error already), using "rownum" like you do isn't very consistent. Not really sure about the requirment of "5th row", but no matter. Just keep in mind that the way Oracle assigns a rownum, and the fact you have no sorting/order ... you are - effectively - getting a random row. That is, with no data changing, Oracle may very well retrieve things in a different order due to index, new oracle version, whatever.
If you do actually need the 5th row where you have some sorting (ie 5th largest salary, or 5th record by last name, etc. ), then you may want to consider something like:
select * from (select last_name, salary, row_number() over (order by salary desc) rn from employees) where rn = 5;
or whatever your sort criteria is. Do a search for "Top N" queries if you need more info.
It'll work a bit more consistently. -
Hello,
I have a procedure, which specification is something like that:
procedure proc1 (pcursor OUT SYS_REFCURSOR, parg1 IN NUMBER, parg2 IN NUMBER, ...);Inside the body of proc1 I have
OPEN pcursor FOR
SELECT column1,
column2,
CURSOR (SELECT column1, column2
FROM table2
WHERE <some clauses come here>) icursor1
FROM table1
WHERE <some clauses come here>;In a PL/SQL block I would like to execute proc1 and then to fetch from pcursor. This is what I am doing so far:
DECLARE
ldata SYS_REFCURSOR;
larg1 NUMBER := 123;
larg2 NUMBER := 456;
outcolumn1 dbms_sql.Number_Table;
outcolumn2 dbms_sql.Number_Table;
BEGIN
some_package_name.proc1 (ldata, larg1, larg2, ...);
FETCH ldata BULK COLLECT INTO
outcolumn1, outcolumn2,..., *and here is my problem*;
END;
/How can I rewrite this in order to get the content of icursor1 ?
Thanks a lot!Verdi wrote:
How can I rewrite this in order to get the content of icursor1 ?
Firstly ref cursors contain no data they are not result sets but pointers to compiled SQL statements.
Re: OPEN cursor for large query
PL/SQL 101 : Understanding Ref Cursors
Ref cursors are not supposed to be used within PL/SQL or SQL for that matter, though people keep on insisting on doing this for some reason.
http://download.oracle.com/docs/cd/E11882_01/appdev.112/e10472/static.htm#CIHCJBJJ
Purpose of Cursor Variables
You use cursor variables to pass query result sets between PL/SQL stored subprograms and their clients. This is possible because PL/SQL and its clients share a pointer to the work area where the result set is stored.A ref cursor is supposed to be passed back to a procedural client language, such as Java or .Net.
If you want to re-use a SQL statement in multiple other PL/SQL or SQL statements you would use a view. -
How to execute the packaged procedure(having out param) in TOAD for Oracle
Hi.
Could you help me
How to execute the packaged procedure having out parameters in TOAD for Oralce..
Thanks..Use anonymous PL/SQL block to execute it.
Example.
DECLARE
<out variable name> <out variable data type>;
BEGIN
<package name>.<procedure name>(<out variable name>);
END; -
I have one table as 'A' there are two coulmns as f and s and i want to put all records of column F first and then
i want to put records of S column in table type, then i want to select those records iin OUT cursor
Table: A
F S
1 10
2 20
3 30
OUTPUT IN OUT cursor
1
2
3
10
20
30
Created code is :
Declare
TYPE t_NameRecord IS RECORD (
a1 NUMBER,
b1 NUMBER) ;
Type t1 is table of t_NameRecord;
v_REC t1;
Type T_NonMone IS RECORD (
Str varchar2(90)
Type t_non is table of T_NonMone;
v_rec_non t_non := t_non();
BEGIN
SELECT f, s bulk collect INTO v_REC
FROM a ;
FOR i in v_REC.first ..v_REC.count
loop v_rec_non.EXTEND;
select v_REC(i).a1 into v_rec_non(i) from dual;
End Loop;
FOR i in v_REC.first ..v_REC.count
loop v_rec_non.EXTEND;
select v_REC(i).b1 into v_rec_non(i) from dual;
End Loop;
-- Here i want to select records from v_rec_non and want as OUT cursor.
END;Do not do this using PL/SQL. Use SQL only.
E.g.
select f from tableA
union all
select s from tableAThe approach you use makes heavily use of private process memory. This will not scale. It also attempts to cache SQL data in PL/SQL for use via SQL by a client. Not a robust approach.
If PL/SQL is needed for very complex data transformation not possible using SQL only, then consider writing a PL/SQL pipeline function to perform the transformation.
Also, the following is flawed:
select v_REC(i).b1 into v_rec_non(i) from dual; There is no need to create a SQL cursor, and context switch to the SQL engine, pushing and pulling bind variables, in order to assign one PL/SQL variable another PL/SQL variable's value. Do variable assignment as follows:
v_rec_non(i) := v_REC(i).b1; -
ORA-06537 OUT bind variable bound to an IN position
Sir,
we have migrated our database from oracle 9i to 10g (Release 10.1.0.2.0)..
but while executing a procedure we are getting the following error
ORA-06537:OUT bind variable bound to an IN position
this same procedure is not throwing any error wen we connect the 9i database
we are giving two parameters for this procedure
in that second one is an IN OUT Parameter
another procedure which use the same parameters working properly in 10g and 9i.
we are using PowerBuilder 10 as front end
plz help me to get ride of this prob...You get that error even in 9i if the parameters to the procedure calls are not bound correctly. Check the powerbuilder application to make sure it is binding the parameter types correctly.
SQL> create or replace procedure proc(p_in IN NUMBER, p_out IN OUT NUMBER) is
2 begin
3 null ;
4 end ;
5 /
Procedure created.
SQL> declare
2 l_var1 NUMBER ;
3 l_var2 NUMBER ;
4 begin
5 execute immediate 'begin proc(:in, :out) ; end ;' using OUT l_var1, OUT l_var2 ;
6 end ;
7 /
declare
ERROR at line 1:
ORA-06537: OUT bind variable bound to an IN position
ORA-06512: at line 5
SQL> declare
2 l_var1 NUMBER ;
3 l_var2 NUMBER ;
4 begin
5 execute immediate 'begin proc(:in, :out) ; end ;' using IN l_var1, OUT l_var2 ;
6 end ;
7 /
declare
ERROR at line 1:
ORA-06537: OUT bind variable bound to an IN position
ORA-06512: at line 5
SQL> declare
2 l_var1 NUMBER ;
3 l_var2 NUMBER ;
4 begin
5 execute immediate 'begin proc(:in, :out) ; end ;' using IN l_var1, IN OUT l_var2 ;
6 end ;
7 /
PL/SQL procedure successfully completed.
SQL> disconnect
Disconnected from Oracle9i Enterprise Edition Release 9.2.0.3.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production
SQL> -
How to pass a litral string into cursor variable?
Hi All
I have a code like below:
I need to select the following table,column with the criteria as such but it looks like the literal string does not work for cursor variable.
I can run the SQL in sqlplus but how I can embed that in PL/SQL code??
-Thanks so much for the help
cursor ccol2(Y1 varchar2) is select table_name,column_name from user_tab_columns
where table_name like 'HPP2TT%' and table_name like '%Y1'
and column_name not in ('MEMBERID');Literal strings are fine in a cursor, however, your logic is likely wrong, and you are not using the Y1 parameter to the cursor correctly. If you are looking for tables that either start with HPP2TT or end with Y1 (whatever you pass as Y1), then you need something more like:
cursor ccol2(Y1 varchar2) is
select table_name, column_name
from user_tab_columns
where (table_name like 'HPP2TT%' or
table_name like '%'||Y1) and
column_name not in ('MEMBERID');In the unlikely event that you are lookig for table that actually do start with HPP2TT and end in whatever is passed in Y1 then your query could be simplified to:
cursor ccol2(Y1 varchar2) is
select table_name, column_name
from user_tab_columns
where table_name like 'HPP2TT%'||Y1 and
column_name not in ('MEMBERID');Note in both cases, a single member in-list is bad practice, although Oracle will transform it to an equality predicate instead.
John
Maybe you are looking for
-
IMovie text has unexplained wide right margins
Hi and thanks for taking a look I am making a movie that is subtitled. For awhile I had no problem copy/pasting the subtitles into iMovie's text field, but recently when I copy/paste from MS Word: Mac 2008 12.0.0 I encounter wide right margins that w
-
SOUND for Macbook Pro to emerson TV! HELP
I just recieved an Emerson HDTV and am trying to connect it to my Macbook Pro. By using an HDMI2 cable, I have picture. But, I cannot get the sound. I have plugged in an audio cable (don't know the name of it but it is the type that fits into the
-
Problem Connecting a Windows Computer to Our Domain
I'm trying to connect a windows XP pro computer to a domain. There is an OD replica on the same subnet set as a Backup Domain Controller. The OD master is on a different subnet, it is set as a Primary Domain Controller. The error I'm getting is: The
-
TV 42SL417U Warranty problem -Please Help!
* Please Help: I purchased: 1 x ($699.00) LED TV TOSHIBA | 42SL417U R (09/25/2011) with 4 year warranty: 1 x ($99.99) 4 Year LCD TV Extended PlanFor Item#N82E16889253276 From NewEgg. But when I call Toshiba for support, they say your TV is no longer
-
Image not appearing in the Web Parameter Form
Hello Folks, I have image in the Parameter form, which is not showing up in the Web Parameter Form. I had set up the "REPORTS_PATH" also and still not appearing. Any clue greatly appreciated.. Thanks, Senthil