If condition in a cursor
Can i use a if condition in a cursor, say like if i declare a parameter and then pass a value to the parameter so that i can do different sets of actions depending on the value of the parameter. I am giving a example as below:-
cursor c(x number) is
if x=1 then
/ do this/
else
/do this/
end if;
Please help in resolving the problem.
No you can do that, but you can do something like:
if x=1 then
str := 'select a,b,c ...';
else
str := 'select x,y,z ...';
end if
open c1 for str;
fetch c1 into ....
Similar Messages
-
New condition baffling mouse cursor freezes if I put it on a flat surface even with ac plugged in
Hi all
I am now really stumped. Here is the situation
ac adaptor plugged in mouse freezes
UNTIL I plug in WIRED and working lan cable.
if I unplug the lan cable from the router the mouse cursor freezes.
NOW that would be strange enough BUT if I unplug the LAN cable the mouse freezes again as expected UNTIL I lift up the S10 ( doesn't matter how I do it) the mouse starts to work again!!!! with the ac plugged in. So now you are all thinking it's the ac socket !!! nope thought about that and it's got nothing to do with it. The mouse freezes the moment I put the computer down on a flat surface or even near it.
It's as if the bloody thing is effected by proximity to a mass ? anyone got any ideasHi majorkong,
Additional ideas are possible shorts internal to the system. I definitely have a reason to believe that the unit has a hardware problem. This is either through the touchpad, touchpad cable, or on the motherboard.
As I see here you have already communicated with us before. Here is your previous thread with us.
Have a good night.
Don -
I want to change the condition of my cursor programmatically.
I have two different condition, and a cursor per condition
Declare
c1 is select prod_name ,prod_price,prod_qty*1000
from products
where ABC;
c2 is select prod_name ,prod_price,prod_qty*1000
from products
where DEF;
Is it possible to pass the string in the where condition?
Otherwise i can i do?
PLZ HELP!!Yes it is.
You need a REF CURSOR declared that than can be used for a string you build up yourself
sqlexecute('select prod_name ,prod_price,prod_qty*1000
from products
where ABC');
sqlexecute('select prod_name ,prod_price,prod_qty*1000
from products
where DEF');
procedure sqlexecute(sqlStr IN VARCHAR2)
is
type sqlstring_curs is ref_cursor;
sqlstring_row sqlstring%ROWTYPE;
begin
open sqlstring_curs for sqlStr;
fetch sqlstring_curs into sqlstring_row;
process sqlstring_row.<columnName1>;
process sqlstring_row.<columnName2>;
process sqlstring_row.<columnNamen>;
close sqlstring_curs;
end;
If you have many rows to process then you need to use the
open sqlstring_curs for sqlStr;
loop
fetch sqlstring_curs into sqlstring_row;
exit when sqlstring_curs%NOTFOUND
process sqlstring_row.<columnName1>;
process sqlstring_row.<columnName2>;
process sqlstring_row.<columnNamen>;
end loop;
Hope this helps -
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 -
Dear All,
I got a general question regarding the functionality of a cursor.
I got a cursor which has multiple where conditions like
CURSOR C_EMP(p_empno NUMBER, P_ename in varchar2) IS SELECT EMPNO, ENAME FROM EMP WHERE EMPNO=P_EMPNO AND ENAME=P_ENAME;
Suppose I pass different where conditions to this cursor, does ORACLE does all the functionalities like PARSING, SYNTAX Checking ETC as the Where condition is changing (OR) Oracle will bind the values while executing the cursor, so that it is PARSED ones but EXECUTED MULTIPLE Times.
Appreciate Your response on this.
Thanks,
MK.Hi Maddy,
Cursor is a merory area where parsing of SQl statement is done.
If u will change a condition then surely reparsing will be done.
CURSOR C_EMP(p_empno NUMBER, P_ename in varchar2) IS SELECT EMPNO, ENAME FROM EMP WHERE EMPNO=P_EMPNO AND >ENAME=P_ENAME;
CURSOR C_EMP(p_empno NUMBER, P_ename in varchar2) IS SELECT EMPNO, ENAME FROM EMP WHERE EMPNO=P_EMPNO AND >ENAME=P_ENAME and (other condition);the above two statments are different from each other so surely a reparsing will be done.
but if u r using bind variables in the cursors then no reparsing will be done, it will just exceute..
Go through the below link for more understanding...
[http://download.oracle.com/docs/cd/B28359_01/server.111/b28318/sqlplsql.htm#CNCPT1737]
Regards
Umi -
Looking for CURSOR replacement, please suggest!
Hello Experts,
I having some master tables "#ACTION_MASTER" & "#RPT_MILE_MASTER" and a link table "#ACTION_MILE_RPT_LINK" showing their relationship.
And again I having a derive table "#TBL" to finally update the master table ''#ACTION_MASTER".
I am able to do the task with below approach and I would like to know how to optimize it, please suggest and let me know for any other information. Thanks!
CREATE TABLE #ACTION_MASTER (UID INT, ACTION_ID INT, IS_ACTV BIT)
INSERT INTO #ACTION_MASTER VALUES (1, 102, 1), (2, 103, 1)
--SELECT * FROM #ACTION_MASTER
CREATE TABLE #RPT_MILE_MASTER (UID INT, RPT_ID INT, MILE_ID INT, MILE_STATUS INT)
INSERT INTO #RPT_MILE_MASTER VALUES (1, 12, 1, 5), (2, 13, 2, 2)
--SELECT * FROM #RPT_MILE_MASTER
CREATE TABLE #ACTION_MILE_RPT_LINK (LINK_ID INT, ACTION_ID INT, RPT_ID INT, MILE_ID INT)
INSERT INTO #ACTION_MILE_RPT_LINK VALUES (1, 102, 12, 1), (2, 102, 13, 2), (3, 103, 13, 2)
--SELECT * FROM #ACTION_MILE_RPT_LINK
CREATE TABLE #TBL (RPT_ID INT, MILE_ID INT, MILE_STATUS INT)
INSERT INTO #TBL VALUES (13, 1, 5), (13, 2, 5)
--SELECT * FROM #TBL
DECLARE @ACTION_ID INT
DECLARE DB_CURSOR CURSOR FOR
SELECT DISTINCT ACTION_ID FROM #ACTION_MILE_RPT_LINK WHERE MILE_ID IN (SELECT MILE_ID FROM #TBL WHERE MILE_STATUS = 5)
OPEN DB_CURSOR
FETCH NEXT FROM DB_CURSOR INTO @ACTION_ID
WHILE @@FETCH_STATUS = 0
BEGIN
IF EXISTS(
SELECT * FROM #ACTION_MILE_RPT_LINK
WHERE MILE_ID IN (SELECT MILE_ID FROM #TBL WHERE MILE_STATUS = 5)
AND RPT_ID NOT IN (SELECT DISTINCT RPT_ID FROM #TBL)
AND ACTION_ID = @ACTION_ID)
BEGIN
DECLARE @COMPARE TABLE (RPT_ID INT, MILE_ID INT, MILE_STATUS INT)
INSERT INTO @COMPARE
SELECT RPT_ID, MILE_ID, 5 'MILE_STATUS' FROM #ACTION_MILE_RPT_LINK
WHERE MILE_ID IN (SELECT MILE_ID FROM #TBL WHERE MILE_STATUS = 5)
AND RPT_ID NOT IN (SELECT DISTINCT RPT_ID FROM #TBL)
AND ACTION_ID = @ACTION_ID
IF NOT EXISTS(
SELECT RPT_ID, MILE_ID, MILE_STATUS FROM #RPT_MILE_MASTER WHERE RPT_ID IN (SELECT RPT_ID FROM @COMPARE)
EXCEPT
SELECT RPT_ID, MILE_ID, MILE_STATUS FROM @COMPARE)
BEGIN
UPDATE #ACTION_MASTER SET IS_ACTV = 0 WHERE ACTION_ID = @ACTION_ID
END
END
ELSE
BEGIN
UPDATE #ACTION_MASTER SET IS_ACTV = 0 WHERE ACTION_ID = @ACTION_ID
END
FETCH NEXT FROM DB_CURSOR INTO @ACTION_ID
END
CLOSE DB_CURSOR
DEALLOCATE DB_CURSOR
--SELECT * FROM #ACTION_MASTER
DROP TABLE #ACTION_MASTER
DROP TABLE #RPT_MILE_MASTER
DROP TABLE #ACTION_MILE_RPT_LINK
DROP TABLE #TBLI don't understand the values in #TBL. Why are the manually inserted? Shouldn't they be the same as in #RPT_MILE_MASTER?
Further more I don't understand the condition in the cursor. Both tables have RPT_ID and MILE_ID in common. Either this is a real multivalued relationship, then why do you only filter by MILE_ID? It looks wrong.
You can rewrite your cursor internals without IF's to
WITH Compare ( RPT_ID, MILE_ID, MILE_STATUS )
AS ( SELECT RPT_ID ,
MILE_ID ,
5
FROM #ACTION_MILE_RPT_LINK
WHERE MILE_ID IN ( SELECT MILE_ID
FROM #TBL
WHERE MILE_STATUS = 5 )
AND RPT_ID NOT IN ( SELECT DISTINCT
RPT_ID
FROM #TBL )
AND ACTION_ID = @ACTION_ID
UPDATE #ACTION_MASTER
SET IS_ACTV = 0
WHERE ACTION_ID = @ACTION_ID
AND NOT EXISTS ( SELECT RPT_ID ,
MILE_ID ,
MILE_STATUS
FROM #RPT_MILE_MASTER
WHERE RPT_ID IN ( SELECT RPT_ID
FROM Compare )
EXCEPT
SELECT RPT_ID ,
MILE_ID ,
MILE_STATUS
FROM Compare )
AND EXISTS ( SELECT *
FROM #ACTION_MILE_RPT_LINK
WHERE MILE_ID IN ( SELECT MILE_ID
FROM #TBL
WHERE MILE_STATUS = 5 )
AND RPT_ID NOT IN ( SELECT DISTINCT
RPT_ID
FROM #TBL )
AND ACTION_ID = @ACTION_ID );
UPDATE #ACTION_MASTER
SET IS_ACTV = 0
WHERE ACTION_ID = @ACTION_ID
AND NOT EXISTS ( SELECT *
FROM #ACTION_MILE_RPT_LINK
WHERE MILE_ID IN ( SELECT MILE_ID
FROM #TBL
WHERE MILE_STATUS = 5 )
AND RPT_ID NOT IN ( SELECT DISTINCT
RPT_ID
FROM #TBL )
AND ACTION_ID = @ACTION_ID );
You can now remove the cursor and JOIN the cursors SELECT into both UPDATEs. -
Hi,
I am having the following cursor, which returns 10000 rows.
Cursor c1 is
select * from emp;
I have the following query on the above cursor.
1) Is there any way by which I can directly go to the 1000th row.
2) Since the above cursor has an Emp_Name column, is there any way by which I can directly go to the row having an Emp_Name='Whatever'.
Thanking you in advance for your kind help.
MAKfor the second point you can simple add the where condition in the cursor query, like:
CURSOR c1 IS
SELECT * FROM emp WHERE emp_name = 'Whatever';
if your value is static you can do it this way, else you can write a parameterized cursor as follows:
CURSOR c1(pEmpName VARCHAR2) IS
SELECT * FROM emp WHERE emp_name = pEmpName;
and then open the cursor like this:
OPEN c1('Whatever');
for the first point, going directly to 1000th row, as far as i know, you have to navigate thru the loop. -
Measuring the value of "session_cached_cursors" and "open_cursor"
Friends ,
Recently In my Database production server Oracle10g (version : 10.2.0.1.0.), I got the "open_cursor" and "session_cached_cursors" related error where OEM asks to increase the value . I have increase the value but the problem still is not solved .
Can anybody plz tell me , how can I measure the Standard value of "open_cursor" and also "session_cached_cursors" of my database server ?
Another question ,
SQL> show parameter open_
NAME TYPE VALUE
open_cursors integer 500
In above output , what is the unit of 500 value . Is this value related with the SGA memory area ?shipon_97 wrote:
Thanks all for reply ..
I have another query ...
How can I find the standarnd value of "open_cursor" as well as "session_cached_cursors" parameter value in the respect of my oracle database server . And what are the recommended value of these parameters . I am using oracle database 10g (v-10.2.0.1.0 ) .Shipon,
You can see the values of the parameters in your db with the simple show parameter command,
>
show parameter open_cursors
show parameter session_cached_cursors>
About the settings of the parameters and their optimal value, I guess there wont' be any "concrete" answer to that. Session cached cursors is set to 50 default in Oracle which means 50 cursors can be marked as 'hot cursors' for the the system and will be avoided from the library cache lookup. This also has a condition that the cursor will be marked as hot only when its run for 3 times. So you need to check back with your system that how many queries are actually requiring this optimization. And more over, this is used or said to be used when you are seeing a Library Cache Latch contention. I don't think that just for the sake of change, you need to modify the parameter from default.
The smae is true for the OPEN_CURSORS as well. The value is required to be changed if you are seeing an error about maximum opened cursor exceeding from the set value. Generally , a value of 2000 is enough for most of the systems but again, that may depend on site to site and surely enough , you need to check yours befoe playing around.
HTH
Aman.... -
hi,
i have a problem in this coding.it is only the part of coding.
declare
TYPE invhdr1 IS RECORD (
customer_trx_id NUMBER,
trx_number VARCHAR2(20),
trx_date DATE,
bill_to_customer_id NUMBER,
remit_to_address_id NUMBER,
term_id NUMBER,
bill_to_site_use_id NUMBER,
primary_salesrep_id NUMBER,
interface_header_context VARCHAR2(40),
cust_trx_type_id NUMBER);
invhdr invhdr1;
TYPE inv_rec1 is REF CURSOR RETURN invhdr1;
inv_rec inv_rec1;
begin
if ((p_date is null) and ((p_trx_type is null) or (p_trx_type is not null))) then
OPEN inv_rec
FOR select
r.customer_trx_id customer_trx_id,
r.trx_number trx_number,
r.trx_date trx_date,
r.bill_to_customer_id bill_to_customer_id,
r.remit_to_address_id remit_to_address_id,
r.term_id term_id,
r.bill_to_site_use_id bill_to_site_use_id,
r.primary_salesrep_id primary_salesrep_id,
r.interface_header_context interface_header_context,
r.cust_trx_type_id cust_trx_type_id
from ra_customer_trx_all r
where (
(nvl(r.interface_header_context,'X')=nvl(p_context_new,nvl(r.interface_header_context,'X')))OR
(nvl(r.interface_header_context,'X')=nvl(p_context_new_oe,nvl(r.interface_header_context,'X')))
and r.trx_number >= p_trx_from
and r.trx_number <=p_trx_to
order by r.trx_number;
end if;
loop
FETCH inv_rec INTO invhdr;
--EXIT WHEN inv_rec%NOTFOUND ;
if inv_rec%notfound then
dbms_output.put_line('No Selection made for the parameters passed') ;
dbms_output.put_line('Cursor Name '||v_cursor) ;
gresult := fnd_concurrent.set_completion_status ('WARNING','*** No Selection made for the parameters passed');
return ;
EXIT;
end if;
end loop;
end ;
here
if inv_rec%notfound then
end if;
even if record exists for the cursor it is passing in side the if condition.iam using cursor variable here.
i don't want to use exit when%notfound condition ,because i want to use
fnd_concurrent.set_completion_status ('WARNING','*** No Selection made for the parameters passed');
return ;
for this exit condition.If someone can help me out.It is an urgent .
thanks,
vr.I don't think you can do it exactly as you want. An alternative is to select a separate count of the same query you will use in your ref cursor and check for 0. Please see the modification of your code below.
declare
TYPE invhdr1 IS RECORD (
customer_trx_id NUMBER,
trx_number VARCHAR2(20),
trx_date DATE,
bill_to_customer_id NUMBER,
remit_to_address_id NUMBER,
term_id NUMBER,
bill_to_site_use_id NUMBER,
primary_salesrep_id NUMBER,
interface_header_context VARCHAR2(40),
cust_trx_type_id NUMBER);
invhdr invhdr1;
TYPE inv_rec1 is REF CURSOR RETURN invhdr1;
inv_rec inv_rec1;
v_count NUMBER := 0;
begin
if ((p_date is null) and ((p_trx_type is null) or (p_trx_type is not null))) then
SELECT COUNT(*) INTO v_count FROM
(select
r.customer_trx_id customer_trx_id,
r.trx_number trx_number,
r.trx_date trx_date,
r.bill_to_customer_id bill_to_customer_id,
r.remit_to_address_id remit_to_address_id,
r.term_id term_id,
r.bill_to_site_use_id bill_to_site_use_id,
r.primary_salesrep_id primary_salesrep_id,
r.interface_header_context interface_header_context,
r.cust_trx_type_id cust_trx_type_id
from ra_customer_trx_all r
where (
(nvl(r.interface_header_context,'X')=nvl(p_context_new,nvl(r.interface_header_context,'X')))OR
(nvl(r.interface_header_context,'X')=nvl(p_context_new_oe,nvl(r.interface_header_context,'X')))
and r.trx_number >= p_trx_from
and r.trx_number <=p_trx_to);
IF v_count = 0 THEN
dbms_output.put_line('No Selection made for the parameters passed') ;
dbms_output.put_line('Cursor Name '||v_cursor) ;
gresult := fnd_concurrent.set_completion_status ('WARNING','*** No Selection made for the parameters passed');
EXIT;
end if;
OPEN inv_rec
FOR select
r.customer_trx_id customer_trx_id,
r.trx_number trx_number,
r.trx_date trx_date,
r.bill_to_customer_id bill_to_customer_id,
r.remit_to_address_id remit_to_address_id,
r.term_id term_id,
r.bill_to_site_use_id bill_to_site_use_id,
r.primary_salesrep_id primary_salesrep_id,
r.interface_header_context interface_header_context,
r.cust_trx_type_id cust_trx_type_id
from ra_customer_trx_all r
where (
(nvl(r.interface_header_context,'X')=nvl(p_context_new,nvl(r.interface_header_context,'X')))OR
(nvl(r.interface_header_context,'X')=nvl(p_context_new_oe,nvl(r.interface_header_context,'X')))
and r.trx_number >= p_trx_from
and r.trx_number <=p_trx_to
order by r.trx_number;
end if;
loop
FETCH inv_rec INTO invhdr;
EXIT WHEN inv_rec%NOTFOUND ;
end loop;
end; -
Dynamic boolean expression evaluation
Hey everyone,
We have a table that consists of a couple key columns and a column containing a boolean expression. We want to select a number of rows based on the key columns and evaluate the boolean expression in the expression column for each, only returning the first row wherein the boolean expression evaluates to true.
We are using a context to inject the test variables into the boolean expressions and currently we are selecting all the key rows in a PL/SQL procedure and going through the cursor evaluating each of the boolean expressions with an execute immediate.
The expressions are currently formated in the columns as anonymous PL/SQL blocks that, when called, will either return true or false to the PL/SQL procedure. Upon returning true, the procedure stops looping and returns true to the caller.
Psuedo-code would be:
- set-up sys_context with condition variables
- create cursor for: select * from expression_tbl et where <key matches>
- begin loop through cursor
- execute immediate cursor_row.expression using out :out_is_true
- if out_is_true = 'Y' then return true
- loop
- return false
The expressions (anonymous PL/SQL blocks) from the table look something like this:
begin if ((''||sys_context('ctx', '1')||'' = 'FL') AND (''||sys_context('ctx', '3')||'' BETWEEN 1619 AND 4598) ) then :1 := 'Y'; end if; end;
This works, but it seems like I should be able to do this another way and potentially extract more performance.
So...a couple questions:
1) I have read on ask Tom that a dynamic select statement (rather than an anonymous PL/SQL block) can evaulate the boolean expressions. I.E. rather than use an execute immediate clause on an anonymous PL/SQL block contained in the expression column, I would make the expression column compatible with a where clause and create this dynamic SQL query: 'select count(*) from dual where ' || expression. I would then execute that query and if it returns a row then the expression is true, otherwise it is false. My question is, does anyone think the performance of parsing the SQL and executing it would be better than that of executing an anonymous PL/SQL block for every row? Tom said that the SQL could incur a lot of hard-parses and kill performance, but how deathly is the constant compilation of anonymous PL/SQL blocks as shown above in comparison?
2) Would there be any benefit to pulling the execute routines out of the PL/SQL block and issuing a query such as the following:
select * from expression_tbl et where <key matches> AND pkg.eval_routine(et.expression) = 'Y' AND rownum <= 1.
I realize that the evaulating routine would then need to either perform an execute immediate on et.expression (if we keep the current method in place) or formulate the dynamic SQL statement and execute it. But, could this be faster than doing the same loop through rows explicitely in PL/SQL?
Doing this would trim my PL/SQL down to:
- set up sys_context
- execute the above select statmenet
- if a row is returned then return true otherwise return false
Seems more elegant, but the peformance is all that matters.
3) Is there any built-in routine that I may be able to replace pkg.eval_routine from 2 with that would evaulate boolean expressions for me? Or any other way to inline the idea from 1 with 2? I can't think of one given the dynamic nature of the beast, but...maybe there's something I missed.
Thanks everyone! Hopefully I've expressed myself clearly.Brian - According to Tom Kyte Doing PL/SQL inside Execute Immediate should be faster as you are already within the context of a PL/SQL engine. If we choose to do it in SQL then the PL/SQL engine has to hand it over to the SQL Engine for executing the dynamic Select statements and so might be a little slower. But I am not sure if the difference can be quantifiable unless u do your own test of both evaluators and run them for like a few thousand times in a loop.
If you are using 10g R2 - you might want to look into DBMS_RLMGR package which is the API for the Oracle's version of the embedded business rule manager.
I looked into it but it didn't fit our needs as its deficient with respect to rule versioning and effective and until date based business rule enforcement/ validation.
After taking a shot at designing something home grown I feel its not that difficult to construct one that fit our needs inclusive of the features( rule versioning, effective and until dates) that I listed above as deficiencies in the Oracle embedded rule engine.
If you don't have those requirements may be using the Business Rule manager API of 10g R2 might not be a bad anticipating it will be improved in future versions.
Regards
-Suren -
Hi
I was having a normal cursor and i was looping through it and inserting rows in 3 different tables based on the values.
I was using IF condition in the cursor.
I want to change the For to FORALL using Bulk Fetch so that the performance is improved. But at the same time as i am inserting in 3 tables based on values, how do i use IF condition with FORALL.
I believe, i will have to open 3 cursors and Bulk Fetch and use FOR ALL 3 times, which will not improve my performance.
I am working on oracle 9i v2 and on an average the number of rows would be around 70000
Any Suggestions ???
Regards
NikhilWe can do this with a multi-table INSERT and FORALL. For demo, I've created three tables, T1-3. T1 will hold all our table names, T2 our index names and T3 every other object name.
SQL> CREATE TABLE t1 ( c1 INT, c2 VARCHAR2(30) );
Table created.
SQL> CREATE TABLE t2 ( c1 INT, c2 VARCHAR2(30) );
Table created.
SQL> CREATE TABLE t3 ( c1 INT, c2 VARCHAR2(30) );
Table created.We'll BULK COLLECT some dummy data and then conditionally INSERT it into T1, T2 or T3...
SQL> DECLARE
2
3 /* Associative array types and variables... */
4 TYPE aat_id IS TABLE OF user_objects.object_id%TYPE
5 INDEX BY PLS_INTEGER;
6 TYPE aat_name IS TABLE OF user_objects.object_name%TYPE
7 INDEX BY PLS_INTEGER;
8 TYPE aat_type IS TABLE OF user_objects.object_type%TYPE
9 INDEX BY PLS_INTEGER;
10 aa_ids aat_id;
11 aa_names aat_name;
12 aa_types aat_type;
13
14 BEGIN
15
16 /* SELECT brings three different types of records... */
17 SELECT object_id, object_name, object_type
18 BULK COLLECT INTO aa_ids, aa_names, aa_types
19 FROM user_objects;
20
21 /* Conditional FORALL INSERT... */
22 FORALL i IN aa_ids.FIRST .. aa_ids.LAST
23 INSERT ALL
24 WHEN aa_types(i) = 'TABLE'
25 THEN INTO t1 VALUES ( aa_ids(i), aa_names(i) )
26 WHEN aa_types(i) = 'INDEX'
27 THEN INTO t2 VALUES ( aa_ids(i), aa_names(i) )
28 WHEN aa_types(i) NOT IN ( 'TABLE', 'INDEX' )
29 THEN INTO t3 VALUES ( aa_ids(i), aa_names(i) )
30 SELECT dummy FROM dual;
31
32 END;
33 /
PL/SQL procedure successfully completed.
SQL>
SQL> SELECT 'USER_OBJECTS', COUNT(*) FROM user_objects WHERE object_type = 'TABLE'
2 UNION ALL
3 SELECT 'T1', COUNT(*) FROM t1;
'USER_OBJECT COUNT(*)
USER_OBJECTS 26
T1 26
SQL>
SQL> SELECT 'USER_OBJECTS', COUNT(*) FROM user_objects WHERE object_type = 'INDEX'
2 UNION ALL
3 SELECT 'T1', COUNT(*) FROM t2;
'USER_OBJECT COUNT(*)
USER_OBJECTS 3
T1 3
SQL>
SQL> SELECT 'USER_OBJECTS', COUNT(*) FROM user_objects WHERE object_type NOT IN ( 'TABLE', 'INDEX' )
2 UNION ALL
3 SELECT 'T1', COUNT(*) FROM t3;
'USER_OBJECT COUNT(*)
USER_OBJECTS 20
T1 20Regards
Adrian -
<data>Database error: Invalid operation on null data</data>
at my client place i got this error
here my condition are
in cursor loop i am calling select stmt, its give "0" value
is this mistake for my program
Edited by: OraclePLSQL on Feb 22, 2011 12:13 AMTrans code:
Description:
2/22/2011 00:24:17 22608 Multiple Requirements For Combo Values 6
Input Header
Length = 70
2260800000GAACCTDB.DATABASE.GAFXTEST 2832SUSHMAC
Input Fields
Name Value Size Data Type
SchemaName 0 DBFieldString
flag 0 DBFieldString
Req 0 DBFieldString
ReqStatus 0 DBFieldString
ReqID 0 DBFieldString
UpnUserName 0 DBFieldString
Result Header
Length = 26
Result Fields
Name Value
data "Database error: Invalid operation on null data"
Raw Input
Length = 290
"<SchemaName>Websdb_SECURITY_leefour </SchemaName><flag>C</flag><Req><![CDATA[AUTO COMPLETE]]> </Req><ReqStatus>IN PROCESS </ReqStatus><ReqID>21 </ReqID><UpnUserName>SGDSHGSHSF </UpnUserName>"
Raw Result
Length = 59
<data>Database error: Invalid operation on null data</data>this is transaction hisory -
Dear Friends,
I have procedure to retrieve data from tables, this procedure uses cursor to fetch the records into the required data block.
i need to change the where clause of the query which used to build the cursor during run time based on data will be gathered from another data block. how can i achieve that??
is there any suggestions???
thanks in advance
MohammadHello,
Check Re: Control Block
for changing the WHERE attribute of a block.
In your case, you want to set the WHERE condition for the cursor and this depends on a value or values you get from another block. In this case, it is best to give the user a way to either enter that condition or store the result you get from the other block in a variable and use that variable in your cursor.
You can use a parameter to store that condition and this will be local to the current form. If however you need to get that from another module, then you might need to use a parameter list and you can pass the WHERE condition in there to the module that has your cursor.
Hope this helps. -
Normalcursor vs sys_refcursor
Hi,
In the below code I have open the cursor two times. here, I am getting the cursor is already opened
exception
DECLARE
CURSOR cur_emp IS
SELECT *
FROM emp;
BEGIN
OPEN cur_emp;
OPEN cur_emp;
END;I am using sys_refcursor to open the cursor dynamically. in this case i have opened the cursor two times.
DECLARE
l_curemp sys_refcursor;
BEGIN
OPEN l_curemp FOR SELECT * FROM emp;
OPEN l_curemp FOR SELECT * FROM emp;
END;In the normal cursor i am getting the exception. In the sys_refcursor i did not get cursor is already opened
exception. why?
can any one explain me detailed?>
In the normal cursor i am getting the exception. In the sys_refcursor i did not get cursor is already opened
exception. why?
can any one explain me detailed?http://docs.oracle.com/cd/B14117_01/appdev.101/b10807/13_elems033.htm
>
... The OPEN-FOR statement executes the query associated with a cursor variable. It allocates database resources to process the query and identifies the result set -- the rows that meet the query conditions. The cursor variable is positioned before the first row in the result set
Other OPEN-FOR statements can open the same cursor variable for different queries. You do not need to close a cursor variable before reopening it. When you reopen a cursor variable for a different query, the previous query is lost.
>
Regards,
Dariyoosh
Edited by: dariyoosh on Feb 6, 2013 11:54 AM -
Counting rows for db tables with 500 million+ entries
Hi
SE16 transaction timesout in foreground when showing number of entries for db tables with 500million+ entries. In background this takes too long.
I am writing a custom report to get number of records of a table and using OPEN CURSOR concept to determine number of records.
Is there any other efficient way to read number of records from such huge tables.
OPEN CURSOR l_cursor FOR
SELECT COUNT(*)
FROM (u_str_param-p_tabn) WHERE (l_tab_cond). " u_str_param-p_tabn is the table name in input and l_tab_cond is a
DO. " dynamic where condition
FETCH NEXT CURSOR l_cursor INTO l_new_count.
PACKAGE SIZE p_pack.
IF sy-subrc NE 0.
EXIT.
ELSE.
l_tot_cnt = l_tot_cnt + l_new_count. " l_tot_cnt will contain number of records at end of loops
CLEAR l_new_count.
ENDIF.
ENDDO.
CLOSE CURSOR l_cursor.Hello,
For sure it is a huge number of entries!!!
Is any key-fields?
Use a variable to keep a counter of the key-fields , for example row_table and also a low and high variable .
Try to use a do-loop and in this loop use:
do .
low_row = row_table.
low_high = row_table + 200.000.:increse the select every 200.000 entries
Do "select statement into table" based on the key-fields
For example : if the key-field is the docnr,
Do a "select into table itab where docnr >low_row
and docnr < low_high"
Count the lines of itab and keep them in a variable.
free the itab.
enddo
Good luck.
Antonis
Maybe you are looking for
-
Custom component class is not detecting url parameter
I have a hcsp page, on which i have a link something like this : "<$HttpCgiPath$>?IdcService=CUSTOM_SERVICE&var1=value1" m appending one more parameter in this url through java script. so one is the var1 which is directly here in the url and one m ap
-
Hi! How can I show a HTML-Page in Internet Explorer by clicking a Menu Item or a button? Thx!
-
Safari Not Loading SOME Images
So, I'm on photobucket today, and i see that some of the images don't work. I quit safari and i try again...Same thing. I then go to re-install safari off apple.com and i get to the installer where it tells me "this update requires 10.5.2 or newer. I
-
Epson r2400 Driver Loses Functionality after Installing Digital Camera Raw
I have four Macs at home and two printers. After installing Digital Camera RAW Compatibility Update 2.0 from software update on my Mac Pro and MacBook Pro, the Epson r2400 printer driver no longer works. I can barely get a print out of Aperture and/o
-
Usb port wont work on macbook pro 13" late 2011
Hello, can anyone help please? I have 2 usb ports but only 1 is working correctly, the other wont take flash drives or my iphone 4 they wont show in the finder or anywhere on my macbook, however my wd harddrive works fine in the same port. just to be