PLS-00103: Encountered the symbol "IS" when expecting one of the following - sql

I am trying to create a function right now (instead of a package) that selects the column data that is currently inside of my OP_GUIDE_VIEW.
Just need a function that selects what's there. Not modifying anything, don't think I need parameters or anything either. What I have so far is the following; however, I cannot figure out this error to save my life: - Has an error # IS C1 V_CURSOR;
What I have right now:
create or replace
PACKAGE PKG_OPGUIDE_COLLECTIONDATA AS
type v_cursor is ref cursor
return OPGUIDE_VIEW%rowtype;
c2 v_cursor;
r_c2 c2%rowtype;
function fn_opview return v_cursor
is c1 v_cursor;
begin
open c1 for select * from OPGUIDE_VIEW;
return c1;
end;
begin
c2 := fn_opview;
loop
fetch c2 into r_c2;
exit when c2%notfound;
dbms_output.put_line(initcap(r_c2.JOB_NAME));
end loop;
close c2;
end;
END PKG_OPGUIDE_COLLECTIONDATA;
Error:
PLS-00103: Encountered the symbol "IS" when expecting one of the following:
constant exception <an identifier>
<a double-quoted delimited-identifier> table long double ref
char time timestamp interval date binary national character
nchar
Can give more information if needed.

You're trying to create a package header and body at the same time.
You have to create an header, then a body, with separate queries; here you find something more.
An example of how you could edit your code:
setup:
create table OPGUIDE_VIEW(JOB_NAME varchar2(100));
insert into OPGUIDE_VIEW values ('job1');
insert into OPGUIDE_VIEW values ('job2');
package creation:
CREATE OR REPLACE PACKAGE PKG_OPGUIDE_COLLECTIONDATA AS
FUNCTION fn_opview
RETURN SYS_REFCURSOR;
PROCEDURE printData;
END;
/
CREATE OR REPLACE PACKAGE BODY PKG_OPGUIDE_COLLECTIONDATA AS
FUNCTION fn_opview
RETURN SYS_REFCURSOR IS
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR SELECT * FROM OPGUIDE_VIEW;
RETURN c1;
END;
PROCEDURE printData IS
c2 SYS_REFCURSOR;
r_c2 OPGUIDE_VIEW%ROWTYPE;
BEGIN
c2 := fn_opview();
LOOP
FETCH c2 INTO r_c2;
EXIT WHEN c2%NOTFOUND;
DBMS_OUTPUT.put_line(INITCAP(r_c2.JOB_NAME));
END LOOP;
CLOSE c2;
END;
END PKG_OPGUIDE_COLLECTIONDATA;
Call your procedure:
SQL> set serveroutput on
SQL>
SQL> begin
2 PKG_OPGUIDE_COLLECTIONDATA.printData;
3 end;
4 /
Job1
Job2
PL/SQL procedure successfully completed.
SQL>

Related

How to store result of a function which will return sysrefcursor?

Scenario: there is an procedure inside which we have a cursor.
I need to call a function which will take an input from that cursor value and will return SYS_REFCURSOR.
I need to store that result of function in a different variable/cursor & need to return this value from procedure as out parameter.
I am using Oracle 11g.
How can I proceed?
PFB My Approach:
create or replace procedure prc_test
(p_dept_id in number,
c_detail out sysrefcursor)--need to add extra out parameter
as
var1 varchar2(200) :=null;
begin
open c_detail for
select -1 from dual;
if p_dept_id is not null then
open c_detail for
select emp_no from emp
where dept_id=p_dept_id;
--i need to retrn value of 'get_emp_dtls' function as out parameter.
end if;
end procedure;
/
Function to be called
CREATE OR REPLACE FUNCTION get_emp_dtls
(p_emp_no IN EMP.EMP_NO%TYPE)
RETURN SYS_REFCURSOR
AS
o_cursor SYS_REFCURSOR;
BEGIN
OPEN o_cursor FOR
SELECT
ENAME,
JOB
FROM emp
WHERE EMP_NO = p_emp_no;
RETURN o_cursor;
-- exception part
END;
/
Here is your function that takes a varchar2 variable and returns A refcursor( weakly typed).
CREATE OR replace FUNCTION fn_return_cur(v IN VARCHAR2)
RETURN SYS_REFCURSOR
IS
c1 SYS_REFCURSOR;
BEGIN
OPEN c1 FOR
SELECT 'ABC'
FROM dual
WHERE 'col1' = v;
RETURN c1;
END;
/
Here is the procedure that has a cursor value passed as argument to function and the returned cursor passed as OUT argument.
CREATE OR replace PROCEDURE Pr_pass_out_cur(v_2 OUT SYS_REFCURSOR)
IS
func_arg VARCHAR2(3);
other_arg VARCHAR2(3);
CURSOR c_2 IS
SELECT 'ABC' col1,
'DEF' col2
FROM dual;
BEGIN
LOOP
FETCH c_2 INTO func_arg, other_arg;
EXIT WHEN c_2%NOTFOUND;
v_2 := Fn_return_cur(func_arg);
END LOOP;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
/
Let me know your feedback.

Can anyone resolve my 'cannot access serially reusable package issue'?

Working on below package, when i execute P_proc3 , I receive error as
"ORA-06534: Cannot access Serially Reusable package" Need help in resolving this
I read
"The SERIALLY_REUSABLE pragma indicates that the package state is needed only for the duration of one call to the server (for example, an OCI call to the database or a stored procedure call through a database link). After this call, the storage for the package variables can be reused, reducing the memory overhead for long-running sessions."
But just understood that this package instance will not be in buffer memory.
CODE given below
create or replace PACKAGE BODY COG_MIGR_TRNS
as
PRAGMA SERIALLY_REUSABLE;
function get_itr_nm return varchar2
as
itr_name varchar2(30);
cursor c1 is
select value
from params where obj_id =45877;
begin
open c1;
fetch c1 into itr_name;
close c1;
return itr_name;
EXCEPTION
WHEN OTHERS THEN RAISE;
end;
-----------------------------------
PROCEDURE P_proc1
IS
v_nm varchar(100);
cursor c1 is
select get_iteration_name()
from dual;
BEGIN
open c1;
fetch c1 into v_nm;
close c1;
<Some more code Here using v_nm>
EXCEPTION
WHEN OTHERS THEN RAISE;
end;
------------------------
PROCEDURE P_proc2
IS
v_nm varchar(100);
cursor c1 is
select get_iteration_name()
from dual;
BEGIN
open c1;
fetch c1 into v_nm;
close c1;
<Some more code Here using v_nm>
EXCEPTION
WHEN OTHERS THEN RAISE;
end;
-------------------
PROCEDURE P_proc3
IS
v_nm varchar(100);
cursor c1 is
select get_iteration_name()
from dual;
BEGIN
P_Proc1;
P_Proc2;
EXCEPTION
WHEN OTHERS THEN RAISE;
end;

inconsistent datatypes: when returning table from cursor in a package function - ORACLE

I have the following package. I am trying to fill the records inside the function from a cursor and return the record. I am unsure of how to assign the rows from the cursor into the record variable. I need to return the record so that I could create a materialized view from it.
CREATE OR REPLACE PACKAGE pkg_contrator_of_consultant AS
TYPE cst_record IS RECORD(
consultant_id NUMBER(10));
TYPE cst_id_type IS TABLE OF cst_record;
FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2)
RETURN cst_id_type
PIPELINED;
END;
CREATE OR REPLACE PACKAGE BODY pkg_contrator_of_consultant AS
FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2 )
RETURN cst_id_type
PIPELINED IS
V_cursor_contracotr_id cst_id_type;
CURSOR cursor_contract_name IS
SELECT plc.FK2_CONTRACTOR_ID
FROM lds_consultant cons
INNER JOIN lds_account acc on cons.consultant_id = acc.fk1_consultant_id
INNER JOIN lds_placement plc on acc.account_id = plc.FK1_ACCOUNT_ID
WHERE UPPER(cons.USERNAME) = UPPER(cst_username)
AND UPPER(plc.PLT_TO_PERMANENT) = UPPER('Y');
V_contracotr_id cst_id_type;
BEGIN
FOR rec IN cursor_contract_name LOOP
V_contracotr_id := rec.fk2_contractor_id;
SELECT V_contracotr_id INTO V_cursor_contracotr_id FROM DUAL;
dbms_output.put_line('cst_username : '||cst_username||' V_contracotr_id :'||V_contracotr_id);
END LOOP;
PIPE ROW (V_cursor_contracotr_id);
RETURN;
END fnc_get_contractor_id;
END;
/
In the line
V_contracotr_id := rec.fk2_contractor_id;
It gives the error "inconsistent datatypes: expected UDT got NUMBER" when the column selected by the cursor is of NUMBER type.
FK2_CONTRACTOR_ID NUMBER
Try this:
out_rec cst_record;
CURSOR C1 IS
SELECT ...;
BEGIN
open c1;
LOOP
FETCH c1 INTO out_rec;
exit when c1%notfound;
PIPE ROW(out_rec);
END LOOP;
close c1;
RETURN;
END fnc_get_contractor_id;
UPDATED CODE:
CREATE OR REPLACE PACKAGE pkg_contrator_of_consultant AS
TYPE cst_record IS RECORD(
consultant_id NUMBER(10));
TYPE cst_id_type IS TABLE OF cst_record;
FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2)
RETURN cst_id_type
PIPELINED;
END;
/
CREATE OR REPLACE PACKAGE BODY pkg_contrator_of_consultant AS
FUNCTION fnc_get_contractor_id(cst_username IN VARCHAR2 )
RETURN cst_id_type
PIPELINED IS
CURSOR c1 IS
SELECT plc.FK2_CONTRACTOR_ID
FROM lds_consultant cons
INNER JOIN lds_account acc on cons.consultant_id = acc.fk1_consultant_id
INNER JOIN lds_placement plc on acc.account_id = plc.FK1_ACCOUNT_ID
WHERE UPPER(cons.USERNAME) = UPPER(cst_username)
AND UPPER(plc.PLT_TO_PERMANENT) = UPPER('Y');
out_rec cst_record;
BEGIN
open c1;
LOOP
FETCH c1 INTO out_rec;
exit when c1%notfound;
PIPE ROW(out_rec);
END LOOP;
close c1;
RETURN;
END fnc_get_contractor_id;
END;
/

How to display table from returned cursor in Oracle?

I need to get a table of bank's name which their bsb is equal to value given to the function.
Here is my code:
CREATE OR REPLACE Function FF(BSB_NUMBER IN BANK.BSB#%TYPE) RETURN SYS_REFCURSOR
IS
MY_CURSOR SYS_REFCURSOR;
BEGIN
OPEN MY_CURSOR for
select * from bank where bank.bsb# = BSB_NUMBER;
return MY_CURSOR;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('Error ! There is no such account');
END FF;
/
And I run in with this but doesn't print anything. Appreciate any idea:
SELECT FindBankStaff(012878) FROM BANK;
Don't return the cursor, return the appropriate value.
Finally I saw this answer and implement it to my issue:
CREATE OR REPLACE FUNCTION SOME_FUNC_RETURNING_A_CURSOR RETURN SYS_REFCURSOR IS
csrLocal SYS_REFCURSOR;
BEGIN
OPEN csrLocal FOR SELECT NAME, BSB# FROM BANK;
RETURN csrLocal;
END SOME_FUNC_RETURNING_A_CURSOR;
/
DECLARE
aCursor SYS_REFCURSOR;
someVariable VARCHAR2(40);
some2 number;
BEGIN
aCursor := SOME_FUNC_RETURNING_A_CURSOR;
WHILE TRUE LOOP
FETCH aCursor INTO someVariable,some2;
EXIT WHEN aCursor%NOTFOUND;
DBMS_OUTPUT.PUT(someVariable);
DBMS_OUTPUT.PUT(' ');
DBMS_OUTPUT.PUT_LINE(some2);
END LOOP;
COMMIT;
END;
/
In Toad there is an option to do this.
You just have to create a bind variable as Ref cursor and invoke the procedure or function. Once the process runs successfully, the Data Grid is automatically populated with the result set of the Object (In your case the records from ref cursor). I suppose even in Oracle Sql Developer the Feature has been incorporated.
If you are using SQL Plus* then the best way is to declare a variable as ref cursor. Execute the piece of block and print the output using print command. Hope it helps...

Get all records from a Ref Cursor in a Package

I'd like to fetch each row when I call the following function:
CpuReporting.getgridusage(300)
This function was provided in a CpuReporting package. It has:
Function GetGridUsage(minutes_Input in Number) Return CurGridUsage;
Type CurGridUsage is Ref Cursor Return RecGridUsage;
Type RecGridUsage is Record (ConfigId Number,
Phase VarChar2(400),
Environment VarChar2(400),
SessionStartTime Date,
I've browsed the GetGridUsage function in PL/SQL Developer, it has two parameters: (Result) REF CURSOR and MINUSTES_INPUT IN NUMBER
I want to be able to fetch all the rows and since I haven't worked with Ref Cursor before, I'm really interested in knowing how will you going to write the PL/SQL.
Assuming CpuReporting is the package name, you'd want something like
DECLARE
l_cursor CpuReporting.CurGridUsage;
l_rec CpuReporting.RecGridUsage;
BEGIN
l_cursor := CpuReporting.getGridUsage( 300 );
LOOP
FETCH l_cursor INTO l_rec;
EXIT WHEN l_cursor%notfound;
-- Do something with l_rec. As an example, print the Environment
dbms_output.put_line( l_rec.Environment );
END LOOP;
CLOSE l_cursor;
END;
If you just want to see the output of the function in PL/SQL you can do this
var r refcursor;
exec :r := CpuReporting.getgridusage(300);
print r;