Cursor(s) in procedure
Hi!
In a procedure there are 2 select statements that have to be handled separately because of 2 different conditions:
1. condition:
IF route_id and segment_id IS NULL THEN ...1.statement - selects non-stop flights:
CURSOR c1 IS
SELECT carrier_code, flight_no, from_city, origin, dept_time, to_city, destination, arr_time, flight_date,
aircraft_type, booking_class, service_class, num_of_seats, checked_bag, fare_basis, fare_type, currency, rt_net_fare, tax, surcharges, fare_total
FROM favailability
WHERE (from_city = p_city_o
AND to_city = p_city_d
AND service_class = p_service_class
AND fare_type = p_fare_type
AND flight_date = p_flightdate)
OR (from_city = p_city_d
AND to_city = p_city_o
AND service_class = p_service_class
AND fare_type = p_fare_type_rt
AND flight_date = p_flightdate_rt)
ORDER BY flight_date;2. condition:
ELSE route_id and segment_id IS NOT NULL THEN ...2.statement - select 1-stop flights
CURSOR c1 IS
SELECT *
FROM
SELECT FLIGHT_LEG_ID
, ROUTE_ID
, SEGMENT_ID
, CARRIER_CODE
, FLIGHT_NO
, FROM_CITY
, ORIGIN
, DEPT_TIME
, TO_CITY
, DESTINATION
, ARR_TIME
, FLIGHT_DATE
, ACTUAL_ARRIVAL_DATE
, AIRCRAFT_TYPE
, BOOKING_CLASS
, SERVICE_CLASS
, NUM_OF_SEATS
, CHECKED_BAG
, FARE_BASIS
, FARE_TYPE
, CURRENCY
, RT_NET_FARE
, TAX
, SURCHARGES
, FARE_TOTAL
, MIN(ORIGIN) KEEP (DENSE_RANK FIRST ORDER BY SEGMENT_ID) OVER (PARTITION BY ROUTE_ID) AS ORG
, MIN(DESTINATION) KEEP (DENSE_RANK LAST ORDER BY SEGMENT_ID) OVER (PARTITION BY ROUTE_ID) AS DST
FROM favailability
WHERE route_id IS NOT NULL
AND segment_id IS NOT NULL
WHERE (from_city = p_city_o or to_city = p_city_d)
AND service_class = p_service_class
AND fare_type = p_fare_type
AND flight_date = p_flightdate
OR
(from_city = p_city_d or to_city = p_city_o)
AND service_class = p_service_class
AND fare_type = p_fare_type_rt
AND flight_date = p_flightdate_rt
order by flight_date;My questions are:
1) How to place this in a procedure, FOR, LOOP ...
2) Are 2 cursors necessary or can 1 cursor handle both selects?
Hi there!
1) When you mention FOR...LOOP I'm going to "assume" you mean the following construct:
FOR each_rec IN (<Your cursor SELECT statement here>) LOOP
.....code
.....code
END LOOP;..to loop through the contents of the returned data set and perform operations, checks etc.
2)Your select statements differ in the number of columns returned so that would neccessitate two separate cursors as you have now.
If the fields returned were the SAME you could "potentially" use certain techniques that can selectively execute WHERE clauses based on other variables etc. (as seen at this link: Re: adding dynamic where/and condition to the cursor - however, this may cause unwanted side effects like indexes not being used if present.
As it stands, I would keep the code as it is - it's logically easier to see what is exactly happening and the processing "overhead" of two separate cursros will be absolutely negligible!
HTH - Chris
....Afterthought.....
If you want to place this process into one select statement you could use UNION ALL and erffectively place the PL/SQL IF statements into the WHERE clause in the following manner:
SELECT <fields in FIRST statement>
FROM <table>
WHERE
(route_id IS NULL and segment_id IS NULL) -- This statement controls if the first part of the SELECT statement is executed
AND
...<Rest of WHERE clause in FIRST statement>
UNION ALL
SELECT <fields in SECOND statement>
FROM <table>
WHERE
(route_id IS NOT NULL and segment_id IS NOT NULL) -- This statement controls if the second part of the SELECT statement is executed
AND
...<Rest of WHERE clause in SECOND statement>This should also keep indexes available for use in the optimiser plan!
Edited by: FFS on 30-Oct-2009 13:32
Similar Messages
-
Hi,
I am using 10g and wanted to check if we can use a dynamic cursor in a procedure.
Following is my code and wanted to see if that can work with every query passed as a parameter.
example ,
exec test1 ('select col1, col2, col3 from table1','Two columns Sql')
exec test1 ('select col1 from table2','one columns Sql')
exec test1 ('select col1, col2, col3, col4, col5 from table3','Five columns Sql')
CREATE OR REPLACE procedure test1 (p_sql IN VARCHAR2, p_subject IN VARCHAR2
is
v_cu_string VARCHAR2(2000);
v_string VARCHAR2(2000);
v_sql VARCHAR2(4000);
v_head VARCHAR2(4000);
v_head_sql VARCHAR2(4000);
v_str_sql VARCHAR2(4000);
TYPE cv_typ IS REF CURSOR;
cv cv_typ;
begin
v_sql := p_sql;
OPEN cv FOR v_sql;
LOOP
FETCH cv INTO v_cu_string;
EXIT WHEN cv%NOTFOUND;
------ Processing steps
END LOOP;
CLOSE cv;
END;Thanksuser527060 wrote:
Following is my code and wanted to see if that can work with every query passed as a parameter.
Just curious as to why this is an improvement of
exec test1 ('select col1, col2, col3 from table1','Two columns Sql')
select col1, col2, col3 from table1And
exec test1 ('select col1 from table2','one columns Sql')
select col1 from table2And
exec test1 ('select col1, col2, col3, col4, col5 from table3','Five columns Sql')
select col1, col2, col3, col4, col5 from table3It needs more code from you to build, more code for anyone to enter to execute, limits selects to only one table I would guess also comes with less documentation than SQL.
http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/toc.htm -
Cursor in stored procedure fails
Hi,
In our application we have a stored procedure which is called with in parameters to generate data into some table. This procedure is being called from another procedure.
This procedure has been used to generate data into the table without any problem since oracle 9i. Last year we have upgraded to oracle 11g after that this procedure is failing intermittently to generate data. When this procedure is executed 50 times it fails atleast once to generate data. If we rerun the procedure for the failed case it generates the data without any change to program code nor any change in underlying data. It doesn't fail if we rerun. Therefore we are unable to simulate the problem.
Procedure has got a very simple code.
proc1 (p1 date,p2 date) is
begin
for c1_rec in c1 (select col1,col2
from x,y where x.......)
loop
end loop;
end;
First we thought for some reason this procedure was not executed at all. But it is not the case. Actually it calls the procedure but the cursor inside the procedure doesn't fetch any records. Also it doesn't report any oracle error.
Appreciate if any one can help me in this.
Thanks & Regards,
Rajavaidyanathanraja wrote:
4. If there is a logical error, the same procedure should not generate data when it is rerun. Behaviour should be the same at all times.Incorrect. Something like NLS settings for example can make the same code, behave differently. E.g. a date string is passed and implicitly converted to a date. And this will work for most dates from different session using different NLS settings (e.g. yyyy/mm/dd versus yyyy/dd/mm). And these sessions will provide different results using the same parameters calling the same application code.
There are a number of such run-time factors that influences code.
5. Failed means it didn't generate the expected output. Which means that there is a problem with that SQL being executed the way it is, with the parameters used. You need to isolate the problem further.
6. Parameter values are right.Have you proved that by using a test case that runs the very same SQL via a test proc, using the same parameter, via a job? Ran that test case interactively via sqlplus?
You need to pop the hood and isolate the problem.
7. I came across one blog saying different behaviour for REF CURSOR between oracle 10g and 11g and he says it is oracle bug. I don't know whether it is applicable for this case also.Bahumbug. There are many Oracle bugs. As there is in all software. However, you have not provided any evidence of a bug.
Application code is behaving inconsistently. That is the symptom. Oracle system code is not relevant until you can prove that the inconsistency is not in the application code, but lower down the call stack. -
"multiple cursor in a procedure" is possible?
Hi.. everyone.
Is it possible , "multiple cursor in one procedure"?
For example,
create or replace procedure xxx
is
vAAA varchar2(10);
vBBB varchar2(10);
cursor cur_1 is select .............................;
cursor cur_2 is select .............................;
begin
-- the first cursor
open cur_1;
loop
end loop;
close cur_1;
-- the second cursor
open cur_2;
loop
end loop;
close cur_2;
end;
If it is not possible, what is the way to use
multiple cursor(more than 2) in ONE procedure?
Thanks in advance.
Have a nice day.
Ho.no problem
SQL> drop procedure xxx;
Procedure dropped.
SQL> CREATE OR REPLACE
2 procedure xxx
3 is
4 vAAA varchar2(10);
5 vBBB varchar2(10);
6 cursor cur_1 is select employee_id from employees where rownum < 2;
7 cursor cur_2 is select department_id from departments where rownum < 2;
8
9 begin
10 -----------------------------------------------
11 -- the first cursor
12 -----------------------------------------------
13 dbms_output.put_line('Cursor 1 Result');
14 open cur_1;
15 loop
16 fetch cur_1 into vAAA;
17 exit when cur_1%notfound;
18 dbms_output.put_line(vAAA);
19 end loop;
20 close cur_1;
21 -----------------------------------------------
22 -- the second cursor
23 -----------------------------------------------
24 dbms_output.put_line('Cursor 2 Result');
25 open cur_2;
26 loop
27 fetch cur_2 into vBBB;
28 exit when cur_2%notfound;
29 dbms_output.put_line(vBBB);
30 end loop;
31 close cur_2;
32 -----------------------------------------------
33 end;
34 /
Procedure created.
SQL> execute xxx;
Cursor 1 Result
100
Cursor 2 Result
10
PL/SQL procedure successfully completed. -
Hi to all,
my problem is to open a cursor into a procedure.
The code is the following:
PROCEDURE p_selection_customer
IS
CURSOR cursor_customer IS
SELECT
c_u.id_customer
FROM
customer_unified_a c_u;
BEGIN
FOR record_customer IN cursor_customer LOOP
ROLLBACK;
END LOOP;
END p_selection_customer;
The error is :
Errore(55,3): PL/SQL: SQL Statement ignored
Errore(58,3): PL/SQL: ORA-06552: PL/SQL: Compilation unit analysis terminated ORA-06553: PLS-320: the declaration of the type of this expression is incomplete or malformed
This procedure is defined in the spec. Then I suppose that my problem is that I can't open a cursor into my schema. Do I verify this hypotesys in my schema? Do I have some queries? My schema don't have the dba and sys grants.
Thank'you very match!Hi Alex,
this is the complete script used to generate the table.
Me too, I knew that the partition was transparent to the Cursor statement.
Thank'you very match!
CREATE TABLE "SSVILCID"."TW_E_CUSTOMER_UNIFIED_A"
( "ID_CUSTOMER_UNIFIED" VARCHAR2(27 BYTE) NOT NULL ENABLE,
"START_VALIDITY_DATE" DATE NOT NULL ENABLE,
"START_ASINC_DATE" DATE NOT NULL ENABLE,
"END_ASINC_DATE" DATE,
"CUSTOMER_STATUS" VARCHAR2(255 BYTE),
"TERMINATION_DATE" DATE,
"CUSTOMER_DOMAIN" VARCHAR2(255 BYTE),
"CUSTOMER_CLUSTER" VARCHAR2(255 BYTE),
"CUSTOMER_SENIORITY" DATE,
"ACTIVATION_DATE" DATE,
"ACQUISITION_DATE" DATE,
"ACQUISITION_CHANNEL" VARCHAR2(255 BYTE),
"SUB_ACQUISITION_CHANNEL" VARCHAR2(255 BYTE),
CONSTRAINT "TW_E_CUSTOMER_UNIFIED_A_PK" PRIMARY KEY ("START_ASINC_DATE", "ID_CUSTOMER_UNIFIED", "START_VALIDITY_DATE")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "SYSTEM" ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
PARTITION BY RANGE ("START_ASINC_DATE")
SUBPARTITION BY LIST ("END_ASINC_DATE")
(PARTITION "M200909" VALUES LESS THAN (TO_DATE(' 2009-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
( SUBPARTITION "M200909_N" VALUES (NULL)
TABLESPACE "DATI",
SUBPARTITION "M200909_NN" VALUES (DEFAULT)
TABLESPACE "DATI") ,
PARTITION "M200910" VALUES LESS THAN (TO_DATE(' 2009-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
( SUBPARTITION "M200910_N" VALUES (NULL)
TABLESPACE "DATI",
SUBPARTITION "M200910_NN" VALUES (DEFAULT)
TABLESPACE "DATI") ,
PARTITION "M200911" VALUES LESS THAN (TO_DATE(' 2009-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
( SUBPARTITION "M200911_N" VALUES (NULL)
TABLESPACE "DATI",
SUBPARTITION "M200911_NN" VALUES (DEFAULT)
TABLESPACE "DATI") ,
PARTITION "M200912" VALUES LESS THAN (TO_DATE(' 2010-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
( SUBPARTITION "M200912_N" VALUES (NULL)
TABLESPACE "DATI",
SUBPARTITION "M200912_NN" VALUES (DEFAULT)
TABLESPACE "DATI") ,
PARTITION "M201001" VALUES LESS THAN (TO_DATE(' 2010-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
( SUBPARTITION "M201001_N" VALUES (NULL)
TABLESPACE "DATI",
SUBPARTITION "M201001_NN" VALUES (DEFAULT)
TABLESPACE "DATI") ,
PARTITION "M201002" VALUES LESS THAN (TO_DATE(' 2010-03-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
( SUBPARTITION "M201002_N" VALUES (NULL)
TABLESPACE "DATI",
SUBPARTITION "M201002_NN" VALUES (DEFAULT)
TABLESPACE "DATI") ,
PARTITION "FUTURE" VALUES LESS THAN (MAXVALUE)
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
STORAGE(
BUFFER_POOL DEFAULT)
TABLESPACE "DATI"
( SUBPARTITION "M210001_N" VALUES (NULL)
TABLESPACE "DATI",
SUBPARTITION "M210001_NN" VALUES (DEFAULT)
TABLESPACE "DATI") ) ENABLE ROW MOVEMENT ; -
Can we define cursors from in procedure while using .procedure file?
Hi Team,
Can we define cursors from in procedure while using .procedure file?
I have a catalog procedure in which am using cursors and it is working fine. But while trying to create the same procedure using .procedure , the validation is failing with "An error occurred while parsing your procedure".
Request your suggestions.
Regards,
Krishna TanguduHi Krishna,
I also tried to find the validation for procedure and failed. What was on my mind when I posted earlier was related to Window -> Properties -> SAP HANA -> Modeler -> Validation Rules but this is not the same for procedure.
Also the validation error seems to not being raised by Studio but the server, so it's not a frontend validation anyway.
Trying to replicate your error I create two procedures here and both worked fine with cursor.
The behavior you found was the same I found, the .procedure goes to repository and _SYS_BIC after activation and .hdbprocedure goes to catalog only.
As far as I understood as you are moving from catalog (manually) and it worked on catalog (.hdbprocedure), I could check the declaration of table types of header as it's the main difference.
Despite this investigation of declaration, you can try create it on modeler direct and see what you found on .procedure created. This can speed up investigation.
Regards, Fernando Da Rós
BTW: I'm faced an very strange behavior that each caracter I type on .procedure or .hdbprocedure freezes studio by around 15 seconds ?!?!?!?! (studio rev73) -
Returning SQL cursor from Stored Procedure
Hi,
I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
assume both query returns equal number of rows.. however both are not related to each other..RP wrote:
Hi,
I have a query regarding returning sql cursor from stored procedure to java in oracle 11g.
I want to query some data ex: my query returns A, B, C. Also, now I want to query some other data ex: D, E, F. Now I want to return this data as an sql cursor as a single row . Example: A,B,C,D,E,F. Is it possible to return/create a cursor in stored procedure?
assume both query returns equal number of rows.. however both are not related to each other..It sounds like what you need is a ref cursor.
First thing to remember though is that cursors do not hold any data (see: {thread:id=886365})
In it's simplest form you would be creating a procedure along these lines...
SQL> create or replace procedure get_data(p_sql in varchar2, p_rc out sys_refcursor) is
2 begin
3 open p_rc for p_sql;
4 end;
5 /
Procedure created.
SQL> var rc refcursor;
SQL> exec get_data('select empno, ename, deptno from emp', :rc);
PL/SQL procedure successfully completed.
SQL> print rc;
EMPNO ENAME DEPTNO
7369 SMITH 20
7499 ALLEN 30
7521 WARD 30
7566 JONES 20
7654 MARTIN 30
7698 BLAKE 30
7782 CLARK 10
7788 SCOTT 20
7839 KING 10
7844 TURNER 30
7876 ADAMS 20
7900 JAMES 30
7902 FORD 20
7934 MILLER 10
14 rows selected.
SQL> exec get_data('select deptno, dname from dept', :rc);
PL/SQL procedure successfully completed.
SQL> print rc
DEPTNO DNAME
10 ACCOUNTING
20 RESEARCH
30 SALES
40 OPERATIONS
50 IT SUPPORTWhich takes an SQL statement (as you said that both your queries were unrelated), and returns a ref cursor, and then your Java code would fetch the data using that cursor.
Now, as for getting your rows to columns and combining two queries that do that... something along these lines...
SQL> select * from x;
C
A
B
C
SQL> select * from y;
C
D
E
F
SQL> ed
Wrote file afiedt.buf
1 select x.col1, x.col2, x.col3
2 ,y.col1 as col4
3 ,y.col2 as col5
4 ,y.col3 as col6
5 from (
6 select max(decode(rn,1,col1)) as col1
7 ,max(decode(rn,2,col1)) as col2
8 ,max(decode(rn,3,col1)) as col3
9 from (select col1, rownum rn from (select * from x order by col1))
10 ) x
11 cross join
12 (
13 select max(decode(rn,1,col1)) as col1
14 ,max(decode(rn,2,col1)) as col2
15 ,max(decode(rn,3,col1)) as col3
16 from (select col1, rownum rn from (select * from y order by col1))
17* ) y
SQL> /
C C C C C C
A B C D E F... will do what you ask. For further information about turning rows to columns read the FAQ: {message:id=9360005} -
Error while opening two cursors in same procedure...
Hi :
I have written following Procedure:
Declare
procedure pro_canefortnight_master Is
kr_caneperiodid integer;
last_caneperiod_id number(10,0);
kr_forthnightid integer;
last_forthnight_id number(10,0);
ref_caneperiodid integer;
ref_seasonyrid integer;
ctr integer:= 1;
CURSOR comp_cur IS select * from CMS_SEASON_YEAR_MASTER ;
comp_rec comp_cur%ROWTYPE;
BEGIN
OPEN comp_cur;
FETCH comp_cur INTO comp_rec;
WHILE comp_cur%FOUND
LOOP
kr_caneperiodid:= comp_rec.SEASON_YR_ID;
select max(crayom_db.cr_cane_calender.cr_cane_calender_ID) into last_caneperiod_id from crayom_db.cr_cane_calender;
if last_caneperiod_id <> 0 then
last_caneperiod_id:= last_caneperiod_id + 1;
else
last_caneperiod_id:= 1000000;
end if;
insert into crayom_db.CR_CANE_CALENDER(cr_cane_calender_ID,ad_client_id, ad_org_id, isactive, created, createdby, updated, updatedby,CR_CANE_CALENDER_NAME,DESCRIPTION) values(last_caneperiod_id,11,11,comp_rec.current_season,sysdate,100,sysdate,11,comp_rec.DESC_MA,comp_rec.DESC_EN);
COMMIT;
/*insert into crayom_db.CR_IdBackup(kr_cultivationtypeid,cr_cultivationtypeid) values(kr_cultivationtypeid, last_cultivationtype_id);*/
insert into crayom_db.temp(kr_bpartnerid,cr_bpartnerid) values(comp_rec.season_yr_id,last_caneperiod_id);
commit;
FETCH comp_cur INTO comp_rec;
End LOOP;
close comp_cur;
CURSOR comp_cur1 IS select * from CMS_FORTH_NIGHT_MASTER ;
comp_rec1 comp_cur1%ROWTYPE;
OPEN comp_cur1;
FETCH comp_cur1 INTO comp_rec1;
WHILE comp_cur1%FOUND
LOOP
kr_forthnightid:= comp_rec1.forthnight_id;
select max(crayom_db.cr_cane_calender_period.cr_cane_calender_period_ID) into last_forthnight_id from crayom_db.cr_cane_calender_period;
if last_forthnight_id <> 0 then
last_forthnight_id:= last_forthnight_id + 1;
else
last_forthnight_id:= 1000000;
end if;
if ref_seasonyrid <> comp_rec1.season_yr_id then
ref_seasonyrid:= comp_rec1.season_yr_id;
else
ctr:= ctr + 1;
end if;
SELECT cr_bpartnerid into ref_caneperiodid from crayom_db.temp where kr_bpartnerid = comp_rec1.season_yr_id;
dbms_output.put_line(ref_caneperiodid);
insert into crayom_db.CR_CANE_CALENDER_period(cr_cane_calender_period_ID,ad_client_id, ad_org_id, isactive, created, createdby, updated, updatedby,Enddate,name, startdate, cr_cane_calender_id) values(last_forthnight_id,11,11,comp_rec1.current_season,sysdate,100,sysdate,11,comp_rec1.end_date,'ForthNight' || ctr, comp_rec1.start_date,ref_caneperiodid);
commit;
FETCH comp_cur1 INTO comp_rec1;
End LOOP;
close comp_cur1;
END;
BEGIN
pro_canefortnight_master();
END;
But I am getting following Error:
Error report:
ORA-06550: line 429, column 8:
PLS-00103: Encountered the symbol "COMP_CUR1" when expecting one of the following:
:= . ( @ % ;
ORA-06550: line 433, column 1:
PLS-00103: Encountered the symbol "FETCH" when expecting one of the following:
begin function package pragma procedure subtype type use
<an identifier> <a double-quoted delimited-identifier> form
current cursor
The symbol "begi
ORA-06550: line 472, column 1:
PLS-00103: Encountered the symbol "BEGIN" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
ORA-06550: line 477, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Can any body help me?
Thank You.
Edited by: [email protected] on Oct 22, 2009 4:36 AM[email protected] wrote:
CURSOR comp_cur1 IS select * from CMS_FORTH_NIGHT_MASTER ;
comp_rec1 comp_cur1%ROWTYPE;This is probably the issue. All variable definitions, including cursors, must be in the DEFINE section of a procedure (between either DECLARE ... BEGIN or AS/IS ... BEGIN).
In addition I wanted to note the following:
1. When posting it is helpful to identify your Oracle version (e.g. 10.2.0.4).
2. Any code that is posted should be placed between \ tags to improve readability.
3. It looks like the code is doing "slow by slow" processing (a.k.a single record processing). It could probably be made much cleaner, maintainable and better performing by possibly using INSERT .. AS SELECT ... or something along those lines. -
How to get values from a ref cursor in a procedure
I have a procedure that returns a cursor type of values, but I cannot get the values.
I got error when on how to define the output cursor. Could someone please look at the code and tell me how to correct it?
Thanks in advance.
******************************8
--This is the package
CREATE OR REPLACE PACKAGE Test_SECURITY2 as
type T_RoleTest is ref cursor;
Procedure P_GetUserRole(userID in number, p_cur out T_RoleTest);
end;
CREATE OR REPLACE PACKAGE BODY Test_SECURITY2 as
Procedure P_GetUserRole(userID in number, p_cur out T_RoleTest) as
begin
open p_cur for
select PREO_Role.ROLE_ID,PREO_Role.ROLE_NAME
from preorder.PREO_Role, preorder.PREO_User_Role
where PREO_Role.Role_id = PREO_User_Role.Role_id
and PREO_User_Role.user_id = userid;
end;
end;
--This is the testing code. I got error here
SQL> set serveroutput on;
SQL> execute dbms_output.enable;
PL/SQL procedure successfully completed.
SQL> declare
2 type T_RoleTest is ref cursor;
3 V_UserRole is ref cursor; --how to define the output cursor
4 v_userId number := 42;
5 V_Role_Id number;
6 v_Role_name varchar2(20);
7 begin
8 Test_SECURITY2.P_GetUserRole(v_userId, V_UserRole);
9
10 open V_UserRole;
11 loop
12 fetch V_UserRole into V_Role_Id, v_Role_name;
13
14 EXIT WHEN V_UserRole%NOTFOUND;
15 dbms_output.put_line('RoleID'||v_Role_ID);
16 dbms_output.put_line('Rolename'||v_Role_name);
17
18 end loop;
19
20 end;
21 /
V_UserRole is ref cursor;
ERROR at line 3:
ORA-06550: line 3, column 13:
PLS-00103: Encountered the symbol "IS" when expecting one of the following:
constant exception <an identifier>declare
type T_RoleTest is ref cursor;
v_UserRole T_RoleTest;or just:
declare
v_UserRole Test_Security2.T_RoleTest;And, if you are on 9i or later, you can just use the built-in sys_refcursor type. -
How to give ref cursor in VB procedure call
This is my Oracle Sp
CREATE OR REPLACE PROCEDURE CRD_DMAN.infy_usp_trades_by_broker_bkr
** Procedure name: CRD_DMAN.USP_TRADES_BY_BROKER
** Author's name: Infosys
** Date written: 04/11/07
** Description: Compliance Trade by Borker
** Maintenance history:
** Date Chg req# Name Remarks
** 04/11/07 Infosys Created
p_ordercursor IN OUT infy_pkg_compliance_transact.cur_compliancetrade,
p_startdate IN VARCHAR,
p_enddate IN VARCHAR,
p_fundcode IN cs_fund_config.parent_acct_cd%TYPE,
p_clientcode IN ts_order_alloc.acct_cd%TYPE,
p_brokercode IN ts_order_alloc.exec_broker%TYPE,
p_reportname IN report_log.report_name%TYPE,
p_callingapplication IN report_log.calling_application%TYPE,
p_callinguser IN report_log.calling_user%TYPE
IS
--Declaring Local Variables
v_owner VARCHAR2 (30);
v_startdate VARCHAR2 (10);
v_enddate VARCHAR2 (10);
v_rowcount NUMBER:=0;
v_logrec base_util_pkg.crd_log_record;
exp_error EXCEPTION;
v_fundcodevalue NUMBER;
BEGIN
BEGIN
/*checking if the start date and end date are null and
assigning the sysdate accordingly*/
IF (TRIM(p_startdate) IS NULL )
THEN
v_startdate := TO_CHAR (SYSDATE, 'mm/dd/yy');
ELSE
v_startdate := p_startdate;
END IF;
IF (TRIM(p_enddate) IS NULL )
THEN
v_enddate := TO_CHAR (SYSDATE, 'mm/dd/yy');
ELSE
v_enddate := p_enddate;
END IF;
/*checking if fund code is null and assigning value accordingly*/
IF TRIM (p_fundcode) IS NULL
THEN
v_fundcodevalue := 0;
ELSE
v_fundcodevalue := 1;
END IF;
/*checking if the reportname or calling user or calling
application name*/
IF (p_reportname IS NULL OR p_callinguser IS NULL
OR p_callingapplication IS NULL)
THEN
RAISE exp_error;
END IF;
END;
--opening and fetching the data into cursor
v_logrec.start_time := SYSDATE;
BEGIN
OPEN p_ordercursor
FOR
SELECT
oa.exec_broker EXEC_BROKER_CODE,
b.bkr_name EXEC_BROKER_NAME,
oa.acct_cd CLIENT_CODE,
f.acct_name CLIENT_NAME,
CASE WHEN (Exists (SELECT 1
FROM cs_fund_broker fb
WHERE rel_typ_cd IN('P','M')
AND oa.exec_broker=fb.BKR_CD
AND oa.acct_cd =fb.acct_cd))
THEN 'Y'
ELSE 'N' END DIRECTED_BROKER,
COUNT ( distinct o.order_id) COUNT_TICKNUM,
MAX (o.trade_date) TRADE_DATE,
SUM (oa.exec_amt) BASE_COST,
SUM (oa.commision_amt) TOTAL_COMMISSION,
(SELECT ab.bkr_typ_cd FROM au_broker ab
WHERE ab.au_change_date =(SELECT TO_TIMESTAMP(MAX(ab.au_change_date))
FROM au_broker ab WHERE b.bkr_typ_cd != ab.bkr_typ_cd AND b.bkr_cd = ab.bkr_cd))
BROKER_HISTORY
FROM
ts_order o
JOIN ts_order_alloc oa ON (o.order_id = oa.order_id)
JOIN cs_broker b ON(oa.exec_broker = b.bkr_cd)
JOIN cs_fund f ON(oa.acct_cd = f.acct_cd)
WHERE
o.status = 'ACCT'
AND oa.exec_broker = CASE WHEN TRIM (p_brokercode) IS NULL
THEN oa.exec_broker
ELSE TRIM(p_brokercode) END
AND oa.acct_cd = CASE WHEN TRIM(p_clientcode) IS NULL
THEN oa.acct_cd
ELSE TRIM(p_clientcode) END
AND ((0 = v_fundcodevalue) OR EXISTS (SELECT 1 FROM crd.cs_fund_config cf
WHERE cf.parent_acct_cd =TRIM (p_fundcode)
AND oa.acct_cd = cf.child_acct_cd))
AND o.trade_date BETWEEN TO_DATE (v_startdate, 'mm/dd/yy')
AND TO_DATE (v_enddate, 'mm/dd/yy')
GROUP BY oa.exec_broker, b.bkr_name ,oa.acct_cd ,f.acct_name,oa.directed_broker,b.bkr_typ_cd,b.bkr_cd;
END;
BEGIN
SELECT
owner
INTO
v_owner
FROM
all_objects
WHERE
object_name = 'INFY_USP_TRADES_BY_BROKER_BKR';
v_logrec.end_time := SYSDATE;
v_logrec.user_code := v_owner;
v_logrec.input_param_values := 'INFY_USP_TRADES_BY_BROKER_BKR,'
|| v_startdate
|| ','
|| v_enddate
|| ','
|| p_fundcode
|| ','
|| p_clientcode
|| ','
|| p_brokercode;
v_logrec.report_name := p_reportname;
v_logrec.object_name := 'INFY_USP_TRADES_BY_BROKER_BKR';
v_logrec.rows_returned := v_rowcount;
v_logrec.calling_application := p_callingapplication;
v_logrec.calling_user := p_callinguser;
END;
BEGIN
--calling the procedure to insert values into the report_log table
COMMIT;
SET TRANSACTION READ WRITE;
base_util_pkg.crd_base_util_proc (v_logrec);
SET TRANSACTION READ ONLY;
END;
EXCEPTION
WHEN exp_error
THEN
DBMS_OUTPUT.put_line ('ERROR');
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('ERROR OCCURED' || SQLCODE);
DBMS_OUTPUT.put_line (SQLERRM);
END infy_usp_trades_by_broker_bkr;
END OF CRD_DMAN.USP_TRADES_BY_BROKER
This is my Pakage from where i am using ref cursor
CREATE OR REPLACE PACKAGE CRD_DMAN.infy_pkg_compliance_transact
AS
** Package name : CRD.INFY_PKG_COMPLIANCE_TRANSACTIONS
** Author's name : Infosys
** Date written : 06/11/07
** Project/System : CRD
** Description : Compliance Trades By Borker Package
** Maintenance history:
** Date Chg req# Name Remarks
** 06/11/07 CRD Infosys Created
--Defining The ComplianceTrade Record DataType
TYPE rec_compliancetrade IS RECORD (
exec_broker_code crd.ts_order_alloc.exec_broker%TYPE,
exec_broker_name crd.cs_broker.bkr_name%TYPE,
client_code crd.ts_order_alloc.acct_cd%TYPE,
client_name crd.cs_fund.acct_name%TYPE,
directed_broker crd.ts_order_alloc.directed_broker%TYPE,
count_ticknum crd.ts_order.order_id%TYPE,
trade_date crd.ts_order.trade_date%TYPE,
base_cost crd.ts_order_alloc.cur_base_mkt_val%TYPE,
total_commission crd.ts_order_alloc.commision_amt%TYPE,
broker_history crd.au_broker.bkr_typ_cd%TYPE
--Declaring a variable of rec_auditdata data type
TYPE cur_compliancetrade IS REF CURSOR
RETURN rec_compliancetrade;
END infy_pkg_compliance_transact;
END OF CRD.INFY_PKG_COMPLIANCE_TRANSACTIONS
How to call this SP from VB code with ref cursor parameter?I'm fairly sure that's not possible, since there's nothing in the ODBC spec to allow for ref cursors. The driver has built in support to check for ref cursors that are returned via a stored procedure call, but there's nothing built into the driver to pass one IN. Since a ref cursor can't be constructed on the client side, you'd have to have some sort of structure that allowed you to reference the ref cursor directly in order to be able to pass one back to the database.
Since you're using VB.NET anyway, the better solution is probably just to use ODP.NET instead, which DOES allow you to reference a ref cursor directly, and there are samples that install with ODP.NET that show you how to do that.
Greg -
I am working on procedure, Please give ideas where i can develop this logic more meaning and easy
the logic is as follows
Table1 is having same Id's ABC having same seq number 100 as per legacy data (This is wrong entry in legacy data)
ID -- Seqnum
ABC -- 100
ABC -- 100
I created a table2 where it will have max seqnum from legacy for this ID's for example ABC
ID -- Max seqnum
ABC --500
In my procedure I will have two cursors
First cursor will be have Table1 detail
Second Cursor will have Table2 Details
In above ex the table will have the first record should be unchanged i.e.,
ABC -- 100 --100
but second record will change to
ABC -- 100 -- 501(This next value of the max seq number from table 2/Cursor 2)
I have to create third column which will hold the next seqnumber for that ID ABC
I should load both records changing the seqnumber so I will not have any duplicate records for same ID.
So final records will look like
ID Seq# Final_Seq#
ABC -- 100 -- 100
ABC -- 100 -- 501
Thanks in advance.Adjusted accordingly to the message above
with
data_tab as
(select 'ABC' id,100 seq from dual union all
select 'ABC',100 from dual union all
select 'ABC',100 from dual union all
select 'BCD',110 from dual union all
select 'CDE',120 from dual union all
select 'CDE',120 from dual union all
select 'DEF',130 from dual union all
select 'EFG',140 from dual union all
select 'EFG',140 from dual union all
select 'EFG',140 from dual union all
select 'EFG',240 from dual union all
select 'EFG',240 from dual union all
select 'FGH',150 from dual
max_nums as
(select 'ABC' id,200 max_num from dual union all
select 'BCD',300 from dual union all
select 'CDE',400 from dual union all
select 'DEF',500 from dual union all
-- select 'EFG',600 from dual union all
select 'FGH',700 from dual
select d.id,d.seq,row_number() over (partition by d.id,d.seq order by null) rn,m.max_num,
case when row_number() over (partition by d.id,d.seq order by null) = 1
then d.seq
else nvl(m.max_num,d.seq) + row_number() over (partition by d.id,d.seq order by null) - 1
end new_seq
from data_tab d,
max_nums m
where d.id = m.id(+)
ID
SEQ
RN
MAX_NUM
NEW_SEQ
ABC
100
1
200
100
ABC
100
2
200
201
ABC
100
3
200
202
BCD
110
1
300
110
CDE
120
1
400
120
CDE
120
2
400
401
DEF
130
1
500
130
EFG
140
1
140
EFG
140
2
141
EFG
140
3
142
EFG
240
1
240
EFG
240
2
241
FGH
150
1
700
150 -
Hi All,
Two cursors in the same procedure will slows down the execution ?. Please can any one suggest one this.I aggree with Sundar, you might be able to update this without using a cursor. My general understanding is to avoid using cursor as much as possible for performance reasons, if you are doing a lot of inserts/updates etc. If you are doing lot of updates and you must have to iterate through a loop due to some reason then try to use bulk processing (use bulk inserts, updates, one sql query to access data from database to avoid conext switching etc.).
-
Hi,
1. I am using a cursor XYZ to store some data into a variable @abc and then using this variable as one of the conditions in filling a #TEMP_TABLE in my STORE_PROC procedure. The #TEMP_TABLE does not get populated.
It works fine when I create a temp table and run the same query outside of the stored procedure.
Here is a sample:
DECLARE CURSOR XYZ FOR
SELECT DISTINCT column-name
FROM database name..Table Name
WHERE condition
OPEN XYZ
FETCH XYZ INTO @abc
IF (@@sqlstatus = 2)
BEGIN
........returns an error code
END
WHILE(@@sqlstatus = 0)
BEGIN
INSERT INTO #TEMP_TABLE
SELECT
FROM
WHERE
AND .............. = @abc
END
Please facilitate a solution as to how to get this to work in a stored procedure?
Thank you,
Developer.Seems you question is concerned with MS SQL Server syntax. Here is
the Oracle forum. Nevertheless all you are doing can be completed
using the single sql statement:
INSERT INTO <<temp table>>
SELECT ... FROM ...
WHERE ...
AND ... IN (SELECT UNIQUE column-name
FROM database name..Table Name
WHERE condition)
Rgds. -
Scrollable Cursor in Stored Procedure
I am trying to implement a scrollable cursor that exists in a stored procedure. Here is my situation:
o Oracle 9i (9.2.0.1.0) for both client and server.
o OCI Interface in purely C++ environment
o I am able to compile/link program with 9i client library, and successfully fetch data from a stored proc that contains a nonscrollable/forward only/traditional cursor without any problems.
I have a stored proc that looks like this:
procedure test(
testcursor out cv_types.cv_fit_data
) as
begin
open testcursor
for select data_id,
text
from data;
end test;
This is where I run into problems:
First I allocate an OCIStmt handle and bind it to the proc. Then using the stmt handle that points to the proc, I bind a secondary handle that points to the cursor (testcursor above) by calling OCIBindByPos with type=SQLT_REF (See OCI ref manual on binding ref cursor). Next, I execute the proc via OCIStmtExecute with the mode=OCI_STMT_SCROLLABLE_READONLY using the statement handle that points to the procedure. Then I use that secondary stmt handle to fetch the rows via OCIStmtFetch2(). I am able to fetch the rows if I stick to OCI_FETCH_NEXT, but when I attempt to use any scrollable features such as OCI_FETCH_ABSOLUTE, it bails with an ORA-24391 error. Upon further investigation, I found out that this error occurs when the stmt is not executed with mode=OCI_STMT_SCROLLABLE_READONLY. The clincher is that I did execute in that mode... Has anyone been faced with a similar situation? Am I tackling this the wrong way? Any help, even pointers to any docs I missed on the subject, is greatly appreciated.
Thanks,
Bryan
I am using OCI in C++ to fetch the data via OCIStmtFetch2(...) method.vaidyanathanraja wrote:
4. If there is a logical error, the same procedure should not generate data when it is rerun. Behaviour should be the same at all times.Incorrect. Something like NLS settings for example can make the same code, behave differently. E.g. a date string is passed and implicitly converted to a date. And this will work for most dates from different session using different NLS settings (e.g. yyyy/mm/dd versus yyyy/dd/mm). And these sessions will provide different results using the same parameters calling the same application code.
There are a number of such run-time factors that influences code.
5. Failed means it didn't generate the expected output. Which means that there is a problem with that SQL being executed the way it is, with the parameters used. You need to isolate the problem further.
6. Parameter values are right.Have you proved that by using a test case that runs the very same SQL via a test proc, using the same parameter, via a job? Ran that test case interactively via sqlplus?
You need to pop the hood and isolate the problem.
7. I came across one blog saying different behaviour for REF CURSOR between oracle 10g and 11g and he says it is oracle bug. I don't know whether it is applicable for this case also.Bahumbug. There are many Oracle bugs. As there is in all software. However, you have not provided any evidence of a bug.
Application code is behaving inconsistently. That is the symptom. Oracle system code is not relevant until you can prove that the inconsistency is not in the application code, but lower down the call stack. -
Open ref cursor in a procedure
Hi
I have a procedure which has 3 input parameters and 1 REF CURSOR type OUT parameter.
In the body of the procedure a select query is dynamically being created, and just before the end of the procedure the REF CURSOR is opened for SELECT(dynamic) query
For Ex: Create or replace procedure proc_name(a in number,b in number,c in number,RETVAL OUT REF CURSOR) as
decalre
strQry varchar2(3000);
begin
-- strQry is select query built dynamically
OPEN RETVAL for strQry;
end proc_name;
This procedure is being called by a java application. My question is what the open cursor statement is doing in the procedure?
Any ideas? Thanks!
greddyHi,
As i know, for example if we want to generate a report for some particular records in our project.consider we are using java as front end and oracle as backend. ok. In that case we need to bring the data from backend to front end ,for that in backend (oracle) we can write procedure to perform this task using ref cursors.
Note: ref cursor will provide the most efficient way in bringing the records from back end to front end.
Create or replace procedure proc_name(a in number,b in number,c in number,RETVAL OUT REF CURSOR) as
decalre
strQry varchar2(3000);
begin
-- strQry is select query built dynamically
--if we are using dynamic query, we can filter out the records using id or name or date
once we did, we need to pass the values to calling enviroment, since we declared the ref cursor as out parameter, we can use the ref cursor to pass the values to calling enviroment. Since we are using ref cursor we need to open the cursor for that dynamic query.
OPEN RETVAL for strQry;
end proc_name;
hope this information is some what helpful. if you got any details regarding this please post it..
thanks. -
Hi,
Hope someone can give me few ideas about this:
I have a database table from which I will take each record in a cursor at one time, use that record as IN parameters in a procedure to do modifications on another table and then once it completes it will take the next record from the cursor and execute the procedure again with the new IN parameters from the second record of table1.
Sample Code:
PROCEDURE p_procedure (p_id IN table1.id%TYPE,
p_date IN table1.date%TYPE,
p_code IN table1.code%TYPE) IS
CURSOR c1 IS
SELECT id, date, code
FROM table1
WHERE id = p_id
and date = p_date
and code = p_code;
BEGIN
For crec in c1 LOOP
BEGIN LOOP
UPDATE table2
SET ID = NULL, DATE = NULL, CODE = NULL, PRINT = NULL, TRAN = NULL --updates to columns in table2
WHERE table2.id = p_id
and table2.date = p_date
and table2.code = p_code;
COMMIT;
END LOOP;
END p_procedure;
Is this the right process or is my code wrong???
Thanks
ManojWhat is wrong in having a COMMIT inside a loop? It might only increase the I/O, but the code does work right?The COMMIT says you've finished and can release resources, the loop says you haven't finished and still need them. It's asking for trouble (traditionally in the form of ORA-01555 "Snapshot too old" errors, which confuse developers who thought they were doing the database a favour by saving their work like it was MS Word). It can also complicate restartability, although perversely developers sometimes claim it is necessary in order to allow restarting if a long-running process fails (which it isn't) or to allow monitoring of how far it's got.
At the very least, try COMMIT WRITE BATCH NOWAIT ;)
Maybe you are looking for
-
Under that is says, "To avoid problems with your computer, quit any applications you are not using. Closing windows and removing files from your startusp disk will also help." In the area where it shows what applications/files are running, it only sh
-
Hi, In the 12.1.8 SP 05, when the iGrid cell values set through the java script, the rendering part is not working. For example, The data set returned by iCommand has 25 rows. Java script sets the values in the iGrid from each row. The application wa
-
Preview Default Print Setting "Fit to Page" Problem
Preview.app in Snow Leopard has removed the option to print without scaling, and recreating this behaviour with the remaining options is quite complex and requires 4 extra steps. Steps to Reproduce: 1. Open a document in Preview.app, such as a PDF, o
-
How i can include smarform output as a body text in Email
Hi experts, Can anybody tell me how i can include smartform output ( invoice related data) as a body text in an Email . Regards, Ratheesh
-
How to store movies in oracle 8i
Hi, I'm workin on an oracle 8i based project. In that project I need to store (.dat) movies in database. I'm using Java as my front-end tool. Plz give me the exact procedure to store movies not necessarily .dat, but movies of any format as thinking I