ROWID in Where clause
Hello All,
I have table with 25 columns.
First three columns are composite keys
1. ID, . STORE_NUM, 3. STORE_NUM_WEEK
to update data i have to use all three column in WHERE clause for proper update. So in cursor also i have to select all three rows., Instead i SELECTED ROWID in cursor and used in where caluse in BULK COLLECT and FORALL update. instead of fetching all three rows. IS this the correct approch. WIth ROWID in don't have to use HINTs and the query and updation runs faster then the other( without ROWID).
I was reading on the intenet some where that using ROWID in not advisible in query.
How correct it is in my case.
Please clearify my daughts.
Thank you in Advance
Thank you sundar for your response.
Please look at my procedure. as under . I am posting the same for your consideration. It is updating selective rows only not all rows. As suggested. How can I do in SQL what about the formula to calculate the value to update.
Please ignore the syntex but look ate code and if you have any suggestion.Sorry for BIG CODE Procedure SP_930_End_Of_Week_OH_up (
pSKU In SS_SKU_Store_Week.SKU%Type,
pStore In SS_SKU_Store_Week.Store_Num%Type)
Is
Type tOnHand is table of SS_SKU_Store_Week.End_Of_Week_On_Hand%Type;
Type tPlannedReceipts is table of SS_SKU_Store_Week.Planned_Receipts%Type;
Type tShipmentQuantity is table of SS_SKU_Store_Week.Shipment_Quantity%Type;
Type tWarehouseAllocation is table of SS_SKU_Store_Week.Warehouse_Allocation%Type;
Type tPlannedSalesTW is table of SS_SKU_Store_Week.Distributed_Planned_Sales%Type;
Type tPlannedWeekFlag is table of SS_SKU_Store_Week.Planned_Week_Flag%Type;
Type tOpertunityRating is table of SS_SKU_Store_Week.OPPORTUNITY_RATING%type;
Type tLastWeekEndOfWeekOnHand is table of number index by binary_integer;
Type tEndOfWeekOnHand is table of number index by binary_integer;
Type tRowid Is Table Of ROWID Index By Binary_Integer;
-- vYearWeekKey tYearWeekKey;
vOnHand tOnHand;
vPlannedReceipts tPlannedReceipts;
vShipmentQuantity tShipmentQuantity ;
vWarehouseAllocation tWarehouseAllocation;
vPlannedSalesTW tPlannedSalesTW;
vPlannedWeekFlag tPlannedWeekFlag;
vLastWeekEndOfWeekOnHand tLastWeekEndOfWeekOnHand;
v_total_EndOfWeekOnHand tEndOfWeekOnHand;
vOpertunityRating tOpertunityRating;
vdistributedSales tPlannedSalesTW; -- distributed planned sales
vOpRat tEndOfWeekOnHand;
vRowId tRowId;
vRowId_1 tRowId;
vEndOfWeekOnHand Number;
vFirstWeek Boolean;
vForwardSales Number;
v_idx pls_integer;
CURSOR OpportunityRating_Cursor Is
SELECT Opportunity_Rating,
End_Of_Week_On_Hand,
Decode(PSW_Flag, 0, 0, Distributed_Planned_Sales)
DistributedPlannedSales,
ROWID
FROM SS_SKU_Store_Week
WHERE SKU = pSKU AND
Store_Num = pStore
ORDER BY Year_Week_Key Desc;
--FOR UPDATE;
Cursor EOWOH_Cursor is
SELECT Floor(Starting_On_Hand * On_Hand_Percent) + Contributing_On_Hand OnHand,
(Planned_Receipts * On_Order_Flag) + Contributing_On_Order PlannedReceipts,
Nvl(Shipment_Quantity, 0) ShipmentQuantity,
Decode(PSW_Flag, 0, 0, Distributed_Planned_Sales) DistributedPlannedSales,
Warehouse_Allocation, SS_SKU_Store_Week.ROWID
FROM SS_SKU,
SS_SKU_Store,
SS_SKU_Store_Week
WHERE SS_SKU.SKU = pSKU AND
SS_SKU.SKU = SS_SKU_store.SKU AND
SS_SKU_Store.Store_Num = pStore AND
SS_SKU_Store.SKU = SS_SKU_Store_Week.SKU AND
SS_SKU_Store.Store_Num = SS_SKU_Store_Week.Store_Num
ORDER BY Year_Week_Key;
Begin
vFirstWeek := True;
Open EOWOH_Cursor;
Loop
FETCH EOWOH_Cursor bulk collect
INTO vOnHand,
vPlannedReceipts,
vShipmentQuantity,
vPlannedSalesTW,
vWarehouseAllocation,
vRowID limit 100;
for i in 1..vRowId.count loop
begin
If vFirstWeek Then
vFirstWeek := False;
vLastWeekEndOfWeekOnHand(i) := vOnHand(i);
ElsIf vEndOfWeekOnHand > 0 Then
vLastWeekEndOfWeekOnHand(i) :=vEndOfWeekOnHand;
Else
vLastWeekEndOfWeekOnHand(i) := 0;
End If;
vEndOfWeekOnHand := vLastWeekEndOfWeekOnHand(i)
+ vPlannedReceipts(i)
+ vShipmentQuantity(i)
+ vWarehouseAllocation(i)
- vPlannedSalesTW(i);
v_total_EndOfWeekOnHand(i):=vEndOfWeekOnHand;
exception
when others then
null;
end;
End loop;
forall i in 1..vRowId.count
UPDATE SS_SKU_Store_Week
SET End_Of_Week_On_Hand =
v_total_EndOfWeekOnHand(i)
WHERE ROWID= vRowId(i);
Exit When EOWOH_Cursor%NotFound;
End Loop;
close EOWOH_Cursor;
Commit;
vForwardSales := 0;
v_idx :=1;
vRowId.delete;
vOnHand.delete;
OPEN OpportunityRating_Cursor;
LOOP
FETCH OpportunityRating_Cursor bulk collect into
vOpertunityRating,vOnHand, vdistributedSales,
vRowId limit 100;
FOR i in 1..vRowId.count LOOP
IF vOpertunityRating(i) Is Not Null Then
vOpRat(v_idx):=case vforwardsales
when 0 then 1
else Round(vOnHand(i)/ vForwardSales, 4)
end;
vRowId_1(v_idx) :=vRowId(i);
v_idx :=v_idx+1;
vForwardSales := 0;
END IF;
vForwardSales := vForwardSales + vdistributedSales(i);
END LOOP;
FORALL i in 1..vRowId_1.count
update SS_SKU_Store_Week
SET Opportunity_Rating = vOpRat(i)
Where ROWID= vRowId_1(i);
EXIT WHEN OpportunityRating_Cursor%NOTFOUND;
END LOOP;
CLOSE OpportunityRating_Cursor;
COMMIT;
Exception
When OTHERS Then
Null;
End SP_930_End_Of_Week_OH_up;
Do you have suggestion.
Similar Messages
-
Why I cannot use RowID in where clause but can use it in order by clause
I am on SQL Server 2008.
1. If I use
SELECT (ROW_NUMBER() over
(order by ImportId, ScenarioId, SiteID, AssetID, LocalSKUID, WEEKID, MonthID)) RowID, *
FROM [JnJ_Version1].[dbo].[td_Production_Week]
order by RowID
Statement works
But
2. If I use
SELECT (ROW_NUMBER() over
(order by ImportId, ScenarioId, SiteID, AssetID, LocalSKUID, WEEKID, MonthID)) RowID, *
FROM [JnJ_Version1].[dbo].[td_Production_Week]
where RowID > 10000
I get error, RowID is an invalid column Name why? How to correct query 2.This is due to the logical evaluation order of a SELECT statement. Logically, a SELECT statement is computed in the order:
FROM (which includes JOIN)
WHERE
GROUP BY
HAVING
SELECT
ORDER BY
OFFSET
Thus, you can use what is defined in the SELECT list in the ORDER BY clause, but not in the WHERE clause.
In the case of row_number(), this has immediate repurcussions. row_number() is computed from the rows as they arrive the SELECT clause, and if you then you would filter on the value in the WHERE clause you would be going round in circles.
To do what you are looking for, you use a nested table, for instance with a CTE:
WITH numbering AS (
SELECT (ROW_NUMBER() over
(order by ImportId, ScenarioId, SiteID, AssetID, LocalSKUID, WEEKID, MonthID)) RowID, *
FROM [JnJ_Version1].[dbo].[td_Production_Week]
SELECT *
FROM numbering
WHERE RowID > 10000
Erland Sommarskog, SQL Server MVP, [email protected] -
Using distinct in where clause
Greedings,
I am trying to execute some kind of distinct using rowid in where clause but for some reason im not getting the appropriate result. Any guidance is welcome
SELECT acnt_code,cat,cat_desc,buc FROM so_budgets_cat where
Trim(buc)='S03'
and
NOT exists (SELECT 1
from so_budgets_cat tab2
where ( tab2.cat = so_budgets_cat.cat )
and tab2.ROWID > so_budgets_cat.ROWID
ORDER BY cat,so_budgets_cat.rowidThanks in advanceAdditionally to the fact that we don't have an idea on the expected output, I can't understand the comparison of ROWIDs in your query. These are the logical addresses where the data reside in the disks, comparing them doesn't make sense to me; Oracle DB defines where to store, based on space availability in the disk allocation to the database occupation - and NOT in a logical sequence.
Maybe the existing row is stored in an address that is not a higher number than other, and so it is not being retrieved in your sub-query - hence your test for distinction is failing. -
Pl/sql select distinct in a where clause
Greedings,
I am trying to execute some kind of distinct using rowid in where clause but for some reason im not getting the appropriate result. Any guidance is welcome
SELECT acnt_code,cat,cat_desc,buc FROM so_budgets_cat where
Trim(buc)='S03'
and
NOT exists (SELECT 1
from so_budgets_cat tab2
where ( tab2.cat = so_budgets_cat.cat )
and tab2.ROWID > so_budgets_cat.ROWID
ORDER BY cat,so_budgets_cat.rowidThanks in advanceCan you provide some example data and example output to further clarify?
It might be that you want something like the code below, but it's hard to tell.
SELECT acnt_code
, cat
, cat_desc
, buc
FROM
(SELECT acnt_code
, cat
, cat_desc
, buc
, ROW_NUMBER() OVER (PARTITION BY cat ORDER BY <something>) rn
FROM so_budgets_cat
WHERE Trim(buc)='S03')
WHERE rn = 1; -
Does the 'default where clause' query select the ROWID by default ?
Hi ,
The query in default where property of a data block is as follows:
global.prim_lang = :global.user_lang
and upper(group_name) like upper('%' || :B_apply_inclusions.TI_group_desc || '%')
UNION ALL
select g.rowid, g.group_no
from table1 t,
table 2 g
where :global.prim_lang != :global.user_lang
and upper(g.group_name) = t.key(+)
and :global.user_lang = t.lang(+)
and upper(nvl(t.translated_value, g.group_name)) like upper('%' || :B_apply_inclusions.TI_group_desc || '%')
The g.rowid was added in the UNIONALL portion of the query because the first part of the query was bringing rowid as well.
We are in 10.1.2.3.0 forms version.
However for a user in forms verion 10.1.2.0.2, the query is giving an error " Unable to perform query " - due to mismatch in the number of columns selected in the query union.
because for this user, rowid is not selected as part of default where clause query( 1st part of the query before the unionalll).
If g.rowid is removed from the 2nd part of the query , it errors out in 10.1.2.3.0 forms version.
Could you kindly clarify when this rowid will also be selected by the default where clause of a block and why this issue is occuring?Is this issue related to forms version or any other property of the block? Is it is version based, is there a patch available to deal with the same?
Thanks in Advance.You normally change the default_where block property just when you want to chnage the filter conditions for what is selected from a given block data source.
Querries with union or minus will confuse forms as to the rowid and will no longer be albe to perform the default insert/update/delete, not knowing the rowid and the table to perform the dml on.
A from clause query will be the best way to change dynamically the tables you select from and also the where. But, by using that, if you wish to insert/update/delete, you will have to use on-insert/update/delete triggers where the processing will have to rely on some primary key columns and not on rowid.
Or, instead of a from-clause, you may use a view, but that will definitely be less flexible than a from clause query. -
SQL query in SQL_REDO Logminor showing where clause with ROWID
SQL query in SQL_REDO Logminor showing where clause with ROWID. I dont wanted to use rowid but wanted to use actual value.
OPERATION SQL_REDO SQL_UNDO
DELETE delete from "OE"."ORDERS" insert into "OE"."ORDERS"
where "ORDER_ID" = '2413' ("ORDER_ID","ORDER_MODE",
and "ORDER_MODE" = 'direct' "CUSTOMER_ID","ORDER_STATUS",
and "CUSTOMER_ID" = '101' "ORDER_TOTAL","SALES_REP_ID",
and "ORDER_STATUS" = '5' "PROMOTION_ID")
and "ORDER_TOTAL" = '48552' values ('2413','direct','101',
and "SALES_REP_ID" = '161' '5','48552','161',NULL);
and "PROMOTION_ID" IS NULL
and ROWID = 'AAAHTCAABAAAZAPAAN';
DELETE delete from "OE"."ORDERS" insert into "OE"."ORDERS"
where "ORDER_ID" = '2430' ("ORDER_ID","ORDER_MODE",
and "ORDER_MODE" = 'direct' "CUSTOMER_ID","ORDER_STATUS",
and "CUSTOMER_ID" = '101' "ORDER_TOTAL","SALES_REP_ID",
and "ORDER_STATUS" = '8' "PROMOTION_ID")
and "ORDER_TOTAL" = '29669.9' values('2430','direct','101',
and "SALES_REP_ID" = '159' '8','29669.9','159',NULL);
and "PROMOTION_ID" IS NULL
and ROWID = 'AAAHTCAABAAAZAPAAe';
Please let me know solution/document which will convert SQL redo rowid value with actual value.
Thanks,Please enclose your output within tag so that people here can read it easily and help you. Also the reason that why you want to remove rowid?
Salman
Edited by: Salman Qureshi on Mar 20, 2013 3:53 PM -
Derive found flag in SQL with where clause using TABLE(CAST function
Dear All,
Stored procedure listEmployees
==========================
CREATE OR REPLACE TYPE STRING_ARRAY AS VARRAY(8000) OF VARCHAR2(15);
empIdList STRING_ARRAY
countriesList STRING_ARRAY
SELECT EMP_ID, EMP_COUNTRY, EMP_NAME, FOUND_FLAG_
FROM EMPLOYEE WHERE
EMP_ID IN
(SELECT * FROM TABLE(CAST(empIdList AS STRING_ARRAY))
AND EMP_COUNTRY IN
(SELECT * FROM TABLE(CAST(countriesList AS STRING_ARRAY))
=================
I have a stored procedure which lists the employees using above simple query.
Here I am using table CAST function to find the list of employees in one go
instead of looping through each and every employee
Everything fine until requirements forced me to get the FOUND_FLAG as well.
Now I wanted derive the FOUND_FLAG by using rownum, rowid, decode functions
but I was not successful
Can you please suggest if there is any intelligent way to say weather the
row is found for given parameters in the where clause?
If not I may have to loop through each set of empIdList, countriesList
and find the values individually just to set a flag. In this approach I can’t use
the TABLE CAST function which is efficient I suppose.
Note that query STRING_ARRAY is an VARRAY. It is very big in size and this procedure
suppose to handle large sets of data.
Thanks In advance
Regards
Charan
Edited by: kmcharan on 03-Dec-2009 09:55
Edited by: kmcharan on 03-Dec-2009 09:55If your query returns results, you have found them... so your "FOUND" flag might be a constant,...
-
Index usage in depending on where clause changes.
Hello Friends,
I need your help for one issue.
I have one query , which is using two table Say T1 and T2, where C1 is common column using which both are joined.
C1 is primary key in T1, but no index available in T2 for C1. T1C2 is the column which we want to select.
(Note that Either of table can be a Master table)
Now see the query:
Select T1C2
From T1, T2
where T2.C1 = T1.C1
Here where clause may have other conditions and From clause may have others tables as per requirements.
I want to know that, if, I change the query like following to let my query use the available index of T1.C1.
Select T1C2
from T1, T2
where T1.C1 = T2.C1
Then, Will the query use the available index of T1. and Will i get better performance. Even a little improvement in performance may help me a lot as this kind of query is being used within a where loop (so it is going to be executed multiple times).
Please advise on this..
Regards,
Dipali..Hi,
18:43:17 rel15_real_p>create table t1(c1 number primary key, c2 number);
Table created.
18:43:26 rel15_real_p>create table t2(c1 number, c2 number);
18:45:08 rel15_real_p>
18:45:09 rel15_real_p>begin
18:45:09 2 for i in 1..100
18:45:09 3 loop
18:45:09 4 insert into t1(c1,c2) values (i,i+100);
18:45:09 5 end loop;
18:45:09 6 commit;
18:45:09 7 end;
18:45:09 8 /
PL/SQL procedure successfully completed.
18:45:09 rel15_real_p>
18:45:09 rel15_real_p>
18:45:09 rel15_real_p>begin
18:45:09 2 for i in 1..100
18:45:09 3 loop
18:45:09 4 insert into t2(c1,c2) values (i,i+200);
18:45:09 5 end loop;
18:45:09 6 commit;
18:45:09 7 end;
18:45:09 8 /
18:45:23 rel15_real_p>select count(*) from t1;
COUNT(*)
100
18:45:30 rel15_real_p>select count(*) from t2;
COUNT(*)
100
18:45:49 rel15_real_p>select index_name,index_type from user_indexes where table
_name='T1';
INDEX_NAME INDEX_TYPE
SYS_C0013059 NORMAL
18:48:21 rel15_real_p>set autotrace on
18:52:25 rel15_real_p>Select T1.C2
18:52:29 2 From T1, T2
18:52:29 3 where T2.C1 = T1.C1
18:52:29 4 /
C2
101
102
103
104
105
C2
200
100 rows selected.
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=7 Card=100 Bytes=
900)
1 0 HASH JOIN (Cost=7 Card=100 Bytes=3900)
2 1 TABLE ACCESS (FULL) OF 'T1' (TABLE) (Cost=3 Card=100 By
es=2600)
3 1 TABLE ACCESS (FULL) OF 'T2' (TABLE) (Cost=3 Card=100 By
es=1300)
Statistics
0 recursive calls
0 db block gets
21 consistent gets
0 physical reads
0 redo size
1393 bytes sent via SQL*Net to client
562 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
100 rows processed
18:52:31 rel15_real_p>analyze table t1 compute statistics;
Table analyzed.
18:55:35 rel15_real_p>analyze table t2 compute statistics;
18:55:38 rel15_real_p>set autotrace on
18:55:42 rel15_real_p>Select T1.C2
18:55:43 2 From T1, T2
18:55:45 3 where T2.C1 = T1.C1
18:55:46 4 /
C2
101
102
103
104
105
C2
200
100 rows selected.
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=100 Bytes=7
00)
1 0 MERGE JOIN (Cost=6 Card=100 Bytes=700)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'T1' (TABLE) (Cost=2 Ca
rd=100 Bytes=500)
3 2 INDEX (FULL SCAN) OF 'SYS_C0013059' (INDEX (UNIQUE)) (
Cost=1 Card=100)
4 1 SORT (JOIN) (Cost=4 Card=100 Bytes=200)
5 4 TABLE ACCESS (FULL) OF 'T2' (TABLE) (Cost=3 Card=100 B
ytes=200)
Statistics
1 recursive calls
0 db block gets
23 consistent gets
0 physical reads
0 redo size
1393 bytes sent via SQL*Net to client
562 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
100 rows processed
18:56:56 rel15_real_p>Select T1.C2
18:56:56 2 From T1, T2
18:56:56 3 where T1.C1 = T2.C1
18:56:58 4 /
C2
101
102
103
104
105
C2
200
100 rows selected.
Execution Plan
0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=6 Card=100 Bytes=7
00)
1 0 MERGE JOIN (Cost=6 Card=100 Bytes=700)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'T1' (TABLE) (Cost=2 Ca
rd=100 Bytes=500)
3 2 INDEX (FULL SCAN) OF 'SYS_C0013059' (INDEX (UNIQUE)) (
Cost=1 Card=100)
4 1 SORT (JOIN) (Cost=4 Card=100 Bytes=200)
5 4 TABLE ACCESS (FULL) OF 'T2' (TABLE) (Cost=3 Card=100 B
ytes=200)
Statistics
1 recursive calls
0 db block gets
23 consistent gets
0 physical reads
0 redo size
1393 bytes sent via SQL*Net to client
562 bytes received via SQL*Net from client
8 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
100 rows processed- Pavan Kumar N -
Urgent: Performance problem with where clause using IN and an OR condition
Select statement is:
select fl.feed_line_id
from ap_expense_feed_lines_all fl
where ((:1 is not null and
fl.feed_line_id in (select distinct r2.object_id
from xxdl_pcard_wf_routing_lists r2,
per_people_f hr2
where upper(hr2.full_name) like upper(:1||'%')
and hr2.person_id = r2.person_id
and r2.fyi_list is null
and r2.sequence_number <> 0))
or
(:1 is null))
If I modify the statement to remove the "or (:1 is null))" part at the bottom of the where clause, it returns in .16 seconds. If I modify the statement to only contain the "(:1 is null))" part of the where clause, it returns in .02 seconds. With the whole statement above, it returns in 477 seconds. Anyone have any suggestions?
Explain plan for the whole statement is:
(1) SELECT STATEMENT CHOOSE
Est. Rows: 10,960 Cost: 212
FILTER
(2) TABLE ACCESS FULL AP.AP_EXPENSE_FEED_LINES_ALL [Analyzed]
(2) Blocks: 8,610 Est. Rows: 10,960 of 209,260 Cost: 212
Tablespace: APD
(6) TABLE ACCESS BY INDEX ROWID HR.PER_ALL_PEOPLE_F [Analyzed]
(6) Blocks: 4,580 Est. Rows: 1 of 85,500 Cost: 2
Tablespace: HRD
(5) NESTED LOOPS
Est. Rows: 1 Cost: 4
(3) TABLE ACCESS FULL XXDL.XXDL_PCARD_WF_ROUTING_LISTS [Analyzed]
(3) Blocks: 19 Est. Rows: 1 of 1,303 Cost: 2
Tablespace: XXDLD
(4) UNIQUE INDEX RANGE SCAN HR.PER_PEOPLE_F_PK [Analyzed]
Est. Rows: 1 Cost: 1
Thanks in advance,
PeterThanks for the reply, but I have already checked what you are suggesting and I am pretty sure those are not causing the problem. The hr2.full_name column has an upper index and the (4) line of the explain plan shows that index being used. In addition, that part of the query executes on its own quickly.
Because the sql is not displayed in an indented format on this page it is a little hard to understand the structure so I am going to restate what is happening.
My sql is:
select a_column
from a_table
where ((:1 is not null) and a_column in (sub-select statement)
or
(:1 is null))
The :1 bind variable is set to a varchar2 entered on the screen of an application.
If I execute either part of the sql without the OR condition, performance is good.
If the :1 bind variable is null with the whole sql statement (so all rows or a_table are returned), performance is still good.
If the :1 bind variable is a not-null value with the whole sql statement, performance stinks.
As an example:
where (('wa' is not null) and a_column in (sub-select statement)) -- fast
where (('wa' is null)) -- fast
where (('' is not null) and a_column in (sub-select statement) -- fast
or
('' is null))
where (('wa' is not null) and a_column in (sub-select statement) -- slow
or
('wa' is null)) -
Performance - composite index with 'OR' in 'WHERE' clause
I have a problem with the performance of the following query:
select /*+ index_asc(omschact oma_index1) */ knr, projnr, actnr from omschact where ((knr = 100 and actnr > 30) or knr > 100)
and rownum = 1;
(rownum used only for test purpose)
index:
create index on omschact (knr, projnr);
Execution plan:
Id Operation
0 SELECT STATEMENT
1 COUNT STOPKEY
2 TABLE ACCESS BY INDEX ROWID
3 INDEX FULL SCAN
If I'm correct, the 'OR' in the 'WHERE' clause is responsible for the INDEX FULL SCAN, what makes the query slow.
A solution would be then to separate the 'WHERE' clause in 2 separate select's (1 with 'knr = 100 and actnr > 30' and 1 with 'knr > 100' and combine the results with a UNION ALL.
Since it's necessary to have all rows in ascending order (oma_index1) I still have to use an ORDER BY to make sure the order of the rows is correct. This results again in a (too) low performance.
Another solution that does the trick is to create an index with the 2 fields (knr, projnr) concatenated and to use the same in the 'WHERE' clause:
create index oma_index2 on omschact (knr || projnr);
select /*+ index_asc(omschact oma_index2) */ knr, projnr, actnr from omschact where (knr || projnr) > 10030;
I just can't believe this work-around is the only solution, so I was hoping that someone here knows of a better way to solve this.padders,
I'll give the real data instead of the example. The index I really use consists of 4 fields. In this table the fields are just numbers, but in other tables I need to use char-fields in indexes, so that's why I concatenate instead of using formula's (allthough I would prefer the latter).
SQL> desc omschact
Name Null? Type
KNR NOT NULL NUMBER(8)
PROJNR NOT NULL NUMBER(8)
ACTNR NOT NULL NUMBER(8)
REGELNR NOT NULL NUMBER(3)
REGEL CHAR(60)
first methode:
SQL> create index oma_key_001(knr,projnr,actnr,regelnr);
Index created.
SQL> select /*+ index_asc(omschact oma_key_001) */ * from omschact where
2 (knr > 100 or
3 (knr = 100 and projnr > 30) or
4 (knr = 100 and projnr = 30 and actnr > 100000) or
5 (knr = 100 and projnr = 30 and actnr = 100000 and regelnr >= 0));
Execution Plan
Plan hash value: 1117430516
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 11M| 822M| 192K (1)| 00:38:26 |
| 1 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 11M| 822M| 192K (1)| 00:38:26 |
|* 2 | INDEX FULL SCAN | OMA_KEY_001 | 11M| | 34030 (1)| 00:06:49 |
Predicate Information (identified by operation id):
2 - filter("KNR">100 OR "KNR"=100 AND "PROJNR">30 OR "KNR"=100 AND "PROJNR"=30
AND "ACTNR">100000 OR "ACTNR"=100000 AND "KNR"=100 AND "PROJNR"=30 AND
"REGELNR">=0)
second method (same index):
SQL> select * from (
2 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr > 100
3 union all
4 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr > 30
5 union all
6 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr = 30 and actnr > 100000
7 union all
8 select /*+ index_asc(omschact oma_key_001) */ * from omschact where knr = 100 and projnr = 30 and actnr = 100000 and regelnr > 0)
9 order by knr, projnr, actnr, regelnr;
Execution Plan
Plan hash value: 292918786
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 11M| 1203M| | 477K (1)| 01:35:31 |
| 1 | SORT ORDER BY | | 11M| 1203M| 2745M| 477K (1)| 01:35:31 |
| 2 | VIEW | | 11M| 1203M| | 192K (1)| 00:38:29 |
| 3 | UNION-ALL | | | | | | |
| 4 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 11M| 822M| | 192K (1)| 00:38:26 |
|* 5 | INDEX RANGE SCAN | OMA_KEY_001 | 11M| | | 33966 (1)| 00:06:48 |
| 6 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 16705 | 1272K| | 294 (1)| 00:00:04 |
|* 7 | INDEX RANGE SCAN | OMA_KEY_001 | 16705 | | | 54 (0)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 47 | 3666 | | 4 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | OMA_KEY_001 | 47 | | | 3 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 1 | 78 | | 4 (0)| 00:00:01 |
|* 11 | INDEX RANGE SCAN | OMA_KEY_001 | 1 | | | 3 (0)| 00:00:01 |
Predicate Information (identified by operation id):
5 - access("KNR">100)
7 - access("KNR"=100 AND "PROJNR">30)
9 - access("KNR"=100 AND "PROJNR"=30 AND "ACTNR">100000)
11 - access("KNR"=100 AND "PROJNR"=30 AND "ACTNR"=100000 AND "REGELNR">0)
third method:
SQL> create index oma_test(to_char(knr,'00000000')||to_char(projnr,'00000000')||to_char(actnr,'00000000')||to_char(regelnr,'000'));
Index created.
SQL> select /*+ index_asc(omschact oma_test) */ * from omschact where
2 (to_char(knr,'00000000')||to_char(projnr,'00000000')||
3 to_char(actnr,'00000000')||to_char(regelnr,'000')) >=
4 (to_char(100,'00000000')||to_char(30,'00000000')||
5* to_char(100000,'00000000')||to_char(0,'000'))
Execution Plan
Plan hash value: 424961364
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 553K| 55M| 1712 (1)| 00:00:21 |
| 1 | TABLE ACCESS BY INDEX ROWID| OMSCHACT | 553K| 55M| 1712 (1)| 00:00:21 |
|* 2 | INDEX RANGE SCAN | OMA_TEST | 99543 | | 605 (1)| 00:00:08 |
Predicate Information (identified by operation id):
2 - access(TO_CHAR("KNR",'00000000')||TO_CHAR("PROJNR",'00000000')||TO_CHAR("
ACTNR",'00000000')||TO_CHAR("REGELNR",'000')>=TO_CHAR(100,'00000000')||TO_CHAR(3
0,'00000000')||TO_CHAR(100000,'00000000')||TO_CHAR(0,'000')) -
Trouble using a function in the where clause
Hello,
I am using a function found at ask.tom.oracle.com which converts a long data type to a character. The function is returning an error when it is placed in the where clause. The sql statement , error message and the function from ask tom are shown below. Does anyone know how to fix this?
<pre>
SELECT A.FLDPHYSICAL,
A.FLDEXPOSURE,
A.FLDDATEDUE,
A.FLDDATELAST,
A.FLDEMPLOYEE,
B.FLDBDATE,
B.FLDMAILSTOP,
B.FLDREC_NUM,
B.FLDLNAME,
B.FLDMI,
B.FLDFNAME,
B.FLDBDATE,
B.FLDDEPT,
B.FLDSTATUS,
B.FLDSSN,
B.FLDHOMEPHON,
B.FLDWORKPHON,
B.FLDID,
B.FLDDIVISION
FROM REQEXAM A,
EMPLOYEE B,
EMPLOYEE_MEMO C
WHERE A.FLDEMPLOYEE = B.FLDREC_NUM
AND b.flduserstr = c.fldrec_num
AND OHM_PKG.GET_LONG('EMPLOYEE_MEMO', 'FLDDATA', C.ROWID) LIKE '%CDL YES%'
AND A.FLDDATEDUE > '01/01/1900'
AND A.FLDPHYSICAL ='CDP'
ORDER BY B.FLDDIVISION,
B.FLDLNAME,
B.FLDFNAME,
B.FLDMI,
A.FLDDATEDUE
The error message
Error at Command Line:26 Column:4
Error report:
SQL Error: ORA-00904: "OHM_PKG"."GET_LONG": invalid identifier
00904. 00000 - "%s: invalid identifier"
create or replace
PACKAGE OHM_PKG AS
/* TODO enter package declarations (types, exceptions, methods etc) here */
function getlong( p_tname in varchar2,p_cname in varchar2,p_rowid in rowid ) return varchar2;
END OHM_PKG;
create or replace
PACKAGE BODY OHM_PKG AS
function getlong( p_tname in varchar2,p_cname in varchar2,p_rowid in rowid ) return varchar2 as
l_cursor integer default dbms_sql.open_cursor;
l_n number;
l_long_val varchar2(4000);
l_long_len number;
l_buflen number := 4000;
l_curpos number := 0;
begin
dbms_sql.parse( l_cursor,
'select ' || p_cname || ' from ' || p_tname ||
' where rowid = :x',
dbms_sql.native );
dbms_sql.bind_variable( l_cursor, ':x', p_rowid );
dbms_sql.define_column_long(l_cursor, 1);
l_n := dbms_sql.execute(l_cursor);
if (dbms_sql.fetch_rows(l_cursor)>0)
then
dbms_sql.column_value_long(l_cursor, 1, l_buflen, l_curpos ,
l_long_val, l_long_len );
end if;
dbms_sql.close_cursor(l_cursor);
return l_long_val;
end getlong;
END OHM_PKG;
</prev>Remove the '_' from the function's name as below:
AND OHM_PKG.GETLONG('EMPLOYEE_MEMO', 'FLDDATA', C.ROWID) LIKE '%CDL YES%' -
How to retrieve the 'Where Clause' text?
Hello all,
I have created a package to retrieve all the DML's executed against the database for the day, for a particular user. DBMS_LOGMNR package was used to retrieve DMLs. But the DMLs retrieved have their 'WHERE' clause text converted to ROWID's. I need to find out the 'WHERE' clause with the parameters.
I tried retrieving values from the v$sql views, but that information is cryptic and very volatile.
Is there a way to retrieve the 'Where' clause? If not, is there a way to retrieve the 'WHERE' clause information using a trigger against the corresponding table.
I am desparately lookin'for a solution. Hope someone out there can help me out.
Regards,
Prabu Raghav.Hi Andrew,
Thanks for the suggestion.
I am using Oracle 8i not 9i.FGA using DBMS_RLS let's me add policies and retrieve all other information about a user except the SQL statement that's executed by the user.
I want to retrieve the Current sql statement executed against the table by a particular user and record it.
Any suggestions?
Regards,
Prabu Raghav. -
How to change access path for 'where' clause by using HINTS?
I searched a loooot of posts and haven't found a solution for my case. I don't even know whether it is possible or not. Is it possible to change the sequence of Oracle "Predicate Information"?
Here is my SQL and Oracle's execution plan.
SELECT Max(logId) AS logId FROM online_users_t
WHERE online_users_date >= to_date('2011-09-19 10:00:00') - 3.2 AND online_users_date <= to_date('2011-09-19 10:00:00') AND online_users_result in (1, -1)
GROUP BY online_users_user
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 24800 | 629K| 1336 (1)| 00:00:17 |
| 1 | HASH GROUP BY | | 24800 | 629K| 1336 (1)| 00:00:17 |
|* 2 | TABLE ACCESS BY INDEX ROWID| ONLINE_USERS_T | 38833 | 985K| 1334 (1)| 00:00:17 |
|* 3 | INDEX RANGE SCAN | ONLINE_USERS_T_IDX | 116K| | 313 (1)| 00:00:04 |
Predicate Information (identified by operation id):
2 - filter("ONLINE_USERS_RESULT"=(-1) OR "ONLINE_USERS_RESULT"=1)
3 - access("ONLINE_USERS_DATE">=TO_DATE(' 2011-09-16 05:12:00', 'syyyy-mm-dd
hh24:mi:ss') AND "ONLINE_USERS_DATE"<=TO_DATE(' 2011-09-19 10:00:00', 'syyyy-mm-dd
hh24:mi:ss'))I have 2 conditions in my 'where' clause, one is date range and the other is 'online_users_result in (1, -1)'. It seems that Oracle filter the table by using 'online_users_result in (1, -1)' first, then access it through date range.
What I want to do is firstly filtering the table by using date range followed by other things. How can I do it?
Any clue or help would be highly appreciated.
Thanks in advance.It seems that Oracle filter the table by using 'online_users_result in (1, -1)' first, then access it through date range. No it's not.
What I want to do is firstly filtering the table by using date range followed by other things. How can I do it?That's precisely what it's doing now.
It is using the T_IDX index to quickly find all rows that satisfy the range predicate on the date column.
And then filter those rows to only retrieve the ones that satisfy the other predicate (... in (1,-1)). -
Hello all,
I have created a package to retrieve all the DML's executed against the database for the day, for a particular user. DBMS_LOGMNR package was used to retrieve DMLs. But the DMLs retrieved have their 'WHERE' clause text converted to ROWID's. I need to find out the 'WHERE' clause with the parameters.
I tried retrieving values from the v$sql views, but that information is cryptic and very volatile.
Is there a way to retrieve the 'Where' clause? If not, is there a way to retrieve the 'WHERE' clause information using a trigger against the corresponding table.
I am using oracle 8i and tried SYS_CONTEXT current_sql parameter. But Current_sql is not available in 8i, it's from 9i onwards.
I am desparately lookin'for a solution. Hope someone out there can help me out.
Regards,
Prabu Raghav.Hi Andrew,
Thanks for the suggestion.
I am using Oracle 8i not 9i.FGA using DBMS_RLS let's me add policies and retrieve all other information about a user except the SQL statement that's executed by the user.
I want to retrieve the Current sql statement executed against the table by a particular user and record it.
Any suggestions?
Regards,
Prabu Raghav. -
Hello all,
I have a view called V_MEDGEN_LISTRADIO but I can't run
SELECT * FROM V_MEDGEN_LISTRADIO
ORA-02020: too many database links in useThe cause is that we call in the view 5 tables over dblink and the open_links parameter is set to 4.
What is strange is that when I run this select by adding a where clause then it works!
SELECT * FROM V_MEDGEN_LISTRADIO WHERE SPRR = 3645;Can someone explain me ? (use of index so all tables are not called ???)
ThanksExplain plan for SELECT * FROM V_MEDGEN_LISTRADIO WHERE SPRR = 3645;
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | Inst |IN-OUT|
| 0 | SELECT STATEMENT | | 1 | 244 | 19 (6)| 00:00:01 | | | | |
| 1 | SORT ORDER BY | | 1 | 244 | 19 (6)| 00:00:01 | | | | |
| 2 | NESTED LOOPS | | 1 | 244 | 18 (0)| 00:00:01 | | | | |
| 3 | NESTED LOOPS | | 1 | 218 | 17 (0)| 00:00:01 | | | | |
| 4 | NESTED LOOPS | | 1 | 188 | 15 (0)| 00:00:01 | | | | |
| 5 | NESTED LOOPS | | 3 | 384 | 10 (0)| 00:00:01 | | | | |
| 6 | NESTED LOOPS | | 3 | 186 | 4 (0)| 00:00:01 | | | | |
| 7 | REMOTE | SPRR | 1 | 20 | 2 (0)| 00:00:01 | | | DEV10~ | R->S |
| 8 | REMOTE | MPAT_MF | 3 | 126 | 2 (0)| 00:00:01 | | | DEV10~ | R->S |
| 9 | REMOTE | SPER_P | 1 | 66 | 2 (0)| 00:00:01 | | | ORAP_~ | R->S |
|* 10 | TABLE ACCESS BY GLOBAL INDEX ROWID| DOSSIER_MEDICAL | 1 | 60 | 3 (0)| 00:00:01 | ROWID | ROWID | | |
|* 11 | INDEX RANGE SCAN | DOSMED_MPR_IDX2 | 2 | | 1 (0)| 00:00:01 | | | | |
| 12 | REMOTE | MEP | 1 | 30 | 2 (0)| 00:00:01 | | | ORAP_~ | R->S |
| 13 | REMOTE | SSV | 1 | 26 | 1 (0)| 00:00:01 | | | ORAP_~ | R->S |
Predicate Information (identified by operation id):
10 - filter("DM"."EXAM_TYPE"='TELEM')
11 - access("DM"."MPR"="P"."SPER")
Remote SQL Information (identified by operation id):
7 - SELECT "SPRR","MNEMO" FROM "SPRR" "MP" WHERE "SPRR"=3645 (accessing 'DEV10_DBLK' )
8 - SELECT "SPAT","DU","RMPB","SPRR_MF","AU" FROM "MPAT_MF" "MF" WHERE "SPRR_MF"=3645 AND NVL("AU",:1+1)>=:2 AND
"RMPB"='PRINC' AND "DU"<=:3 (accessing 'DEV10_DBLK' )
9 - SELECT "SPER","NOM","PRENOM","DTE_NAI" FROM "SPER_P" "P" WHERE "SPER"=:1 (accessing 'ORAP_DBLK' )
12 - SELECT "MSJ","MEPNO_SEQ","SSV_OU_PAT_SEJOURNE" FROM "MEP" "MEP" WHERE :1="MSJ" AND :2="MEPNO_SEQ" (accessing 'ORAP_DBLK' )
13 - SELECT "SSV","LIB_1" FROM "SSV" "SSV" WHERE :1="SSV" (accessing 'ORAP_DBLK' )Explain plan for SELECT * FROM V_MEDGEN_LISTRADIO
Plan hash value: 3820716840
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | Inst |IN-OUT|
| 0 | SELECT STATEMENT | | 7 | 1708 | 771 (1)| 00:00:10 | | | | |
| 1 | SORT ORDER BY | | 7 | 1708 | 771 (1)| 00:00:10 | | | | |
| 2 | NESTED LOOPS | | 7 | 1708 | 770 (1)| 00:00:10 | | | | |
| 3 | NESTED LOOPS | | 7 | 1568 | 763 (1)| 00:00:10 | | | | |
| 4 | NESTED LOOPS | | 7 | 1386 | 756 (1)| 00:00:10 | | | | |
| 5 | NESTED LOOPS | | 7 | 1176 | 742 (1)| 00:00:09 | | | | |
| 6 | NESTED LOOPS | | 194 | 24444 | 414 (1)| 00:00:05 | | | | |
| 7 | TABLE ACCESS BY GLOBAL INDEX ROWID| DOSSIER_MEDICAL | 194 | 11640 | 23 (0)| 00:00:01 | ROWID | ROWID | | |
|* 8 | INDEX RANGE SCAN | DOSMED_EXAM_TYPE_IDX2 | 194 | | 1 (0)| 00:00:01 | | | | |
| 9 | REMOTE | SPER_P | 1 | 66 | 2 (0)| 00:00:01 | | | ORAP_~ | R->S |
| 10 | REMOTE | MPAT_MF | 1 | 42 | 2 (0)| 00:00:01 | | | DEV10~ | R->S |
| 11 | REMOTE | MEP | 1 | 30 | 2 (0)| 00:00:01 | | | ORAP_~ | R->S |
| 12 | REMOTE | SSV | 1 | 26 | 1 (0)| 00:00:01 | | | ORAP_~ | R->S |
| 13 | REMOTE | SPRR | 1 | 20 | 1 (0)| 00:00:01 | | | DEV10~ | R->S |
Predicate Information (identified by operation id):
8 - access("DM"."EXAM_TYPE"='TELEM')
Remote SQL Information (identified by operation id):
9 - SELECT "SPER","NOM","PRENOM","DTE_NAI" FROM "SPER_P" "P" WHERE :1="SPER" (accessing 'ORAP_DBLK' )
10 - SELECT "SPAT","DU","RMPB","SPRR_MF","AU" FROM "MPAT_MF" "MF" WHERE NVL("AU",:1+1)>=:2 AND "RMPB"='PRINC' AND "DU"<=:3 AND
:4="SPAT" (accessing 'DEV10_DBLK' )
11 - SELECT "MSJ","MEPNO_SEQ","SSV_OU_PAT_SEJOURNE" FROM "MEP" "MEP" WHERE :1="MSJ" AND :2="MEPNO_SEQ" (accessing 'ORAP_DBLK' )
12 - SELECT "SSV","LIB_1" FROM "SSV" "SSV" WHERE :1="SSV" (accessing 'ORAP_DBLK' )
13 - SELECT "SPRR","MNEMO" FROM "SPRR" "MP" WHERE :1="SPRR" (accessing 'DEV10_DBLK' )
Maybe you are looking for
-
How do I return (to iCloud from MacBook Pro) a playlist of 80 songs that I downloaded? I only needed the songs downloaded temporarily due to no WiFi. I want to keep the playlist in iCloud; just don't want them downloaded. I know how to delete songs,
-
Hi Can anyone give me instructions for deleting an uploaded image without deleting the whole record? For example, I have a record with an uploaded image, the image name stored in the table and the image in a directory. I change my mind and want no im
-
Best way to delegate events to parent
Hi to all. I have a problem with a GUI i'm programming. I have the Shop class that extends a JFrame and have several JPanel and other components. Inside one of this JPanel i have an InventoryPanel that extends JPanel and contains JTextfields and a JL
-
Messages: "Web application processing terminated"
Hello all, When i execute a webtemplate, the message "web application processing is terminated" as a link. Diagnosis are as follows: Diagnosis The system had to terminate processing of the Web application. The reason could be that the system was no l
-
Why have all playlists disappeared?
Loved the idea of itunes match and signed up a year ago, and got a few good months of usage for my $25. Several issues today: 1) iphone 4 & ipad 2: reloads itunes match everytime i go to select a song, then repeats this loop with each new selection;