FORALL BULK COLLECT [message #625427] |
Wed, 08 October 2014 04:34 |
ORAGENASHOK
Messages: 240 Registered: June 2006 Location: Chennai
|
Senior Member |
|
|
when i execute the below standalone proc am getting below error
ORA-06550: line 34, column 62:
PLS-00382:expression is of wrong type
Declare
cursor c1 is
select max(rowid)
from wkly_service_agg
where trunc(edw_report_date) = trunc(to_date('22/08/2014','dd/mm/yyyy'))
group by report_date,week_num,service_group_key,p_pro_key, b_pro_key,
b_sd_key, v_prom_key, t_prot_key,
ni_flg, v_promo_key, service_type_id, subscode_key,
source_system_id,s_prot_key, ENABLED_PLATFORM,
PROMO_KEY,LONG_TERM_DISCOUNT,SPECIAL_OFFER_DISCOUNT,
SPORTS_RELIEF_PROD_KEY,HD_SD,FVA_FLG,BASIS_PRODUCT_KEY,
VOLUME_OF_SERVICE,FL_F_ELIGIBILITY,FL_SOURCE,B_CONTRACT_IND,
B_CONTRACT_REMAINING_KEY,D_MODEL_ID,V_CONTRACT_IND,V_CONTRACT_REMAINING_KEY,
V_CONTRACT_IND,V_CONTRACT_REMAINING_KEY,MID_TIER_DISCOUNT,DISCOUNT_METHOD,
M_PROMO_KEY,REL_DISC_S_KEY;
type t_cur1 is table of c1%rowtype;
ttcur1 t_cur1;
--var_rowid varchar2(1000);
v_num number;
Begin
open c1;
fetch c1 bulk collect into ttcur1 limit 20000 ;
forall i in ttcur1.FIRST .. ttcur1.LAST
delete from wkly_service_agg where rowid = ttcur1(i);
v_num := SQL%ROWCOUNT;
dbms_output.put_line('The count of committed records :'||v_num);
End;
|
|
|
|
|
|
|
|
|
Re: FORALL BULK COLLECT [message #625435 is a reply to message #625432] |
Wed, 08 October 2014 05:06 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
No.
This:
type t_cur1 is table of c1%rowtype;
Needs to be:
type t_cur1 IS TABLE OF UROWID
INDEX BY PLS_INTEGER;
But really the whole thing needs to be a single delete and the use of rowid here is suspect.
@ORAGENASHOK - using max(rowid) like that will delete one random row from each group, is that what you want?
|
|
|
|
Re: FORALL BULK COLLECT [message #625437 is a reply to message #625433] |
Wed, 08 October 2014 05:08 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
ORAGENASHOK wrote on Wed, 08 October 2014 11:02Yes, but the record we expect is more and its taken more time more than an hour and decided to have bulk collect
Bulk collect is not faster than a single delete, usually it's slower, so the above is a reason to do as I suggest.
|
|
|
Re: FORALL BULK COLLECT [message #625440 is a reply to message #625435] |
Wed, 08 October 2014 05:11 |
ORAGENASHOK
Messages: 240 Registered: June 2006 Location: Chennai
|
Senior Member |
|
|
Yes, My batch ran twice for the same set of records mistakenly and i have to delete the duplicated one , unfortunately i dont't have constraints on that table , so i have used this way.
Earlier i am trying to do this with single delete stmt but my environment takes more time as i don't have time, so decided to go with bulk delete.
|
|
|
Re: FORALL BULK COLLECT [message #625441 is a reply to message #625440] |
Wed, 08 October 2014 05:14 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
bulk collect is slower than a single delete.
bulk collect is slower than a single delete.
bulk collect is slower than a single delete.
bulk collect is slower than a single delete.
|
|
|
|
|
|
|
Re: FORALL BULK COLLECT [message #625449 is a reply to message #625445] |
Wed, 08 October 2014 05:31 |
pablolee
Messages: 2882 Registered: May 2007 Location: Scotland
|
Senior Member |
|
|
If your delete is really taking too long and all you want to do it get rid of your duplicates, try something like:
create table new_x as select distinct * from old_x;
drop table old_x purge;
alter table new_x rename to old_x;
create any required indexes and constraints and recompile any stored procedures
|
|
|
Re: FORALL BULK COLLECT [message #625450 is a reply to message #625444] |
Wed, 08 October 2014 05:34 |
Lalit Kumar B
Messages: 3174 Registered: May 2013 Location: World Wide on the Web
|
Senior Member |
|
|
ORAGENASHOK wrote on Wed, 08 October 2014 15:47I don't know First time i heard bulk collect will be slow compared with single stmt
Oracle uses two engines to process PL/SQL code. All procedural code is handled by the PL/SQL engine while all SQL is handled by the SQL statement executor, or SQL engine. There is an overhead associated with each context switch between the two engines.
And that is why SQL is faster than PL/SQL. And that is what CM and MC are trying to explain you.
|
|
|
Re: FORALL BULK COLLECT [message #625453 is a reply to message #625444] |
Wed, 08 October 2014 05:43 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
ORAGENASHOK wrote on Wed, 08 October 2014 11:17@cookiemonster
Modified the below but getting different error
type t_cur1 IS TABLE OF UROWID
INDEX BY PLS_INTEGER;
I changed the type name for my own testing and forgot to change it back, you really should have spotted that.
|
|
|
Re: FORALL BULK COLLECT [message #625455 is a reply to message #625450] |
Wed, 08 October 2014 05:47 |
cookiemonster
Messages: 13920 Registered: September 2008 Location: Rainy Manchester
|
Senior Member |
|
|
Lalit Kumar B wrote on Wed, 08 October 2014 11:34ORAGENASHOK wrote on Wed, 08 October 2014 15:47I don't know First time i heard bulk collect will be slow compared with single stmt
Oracle uses two engines to process PL/SQL code. All procedural code is handled by the PL/SQL engine while all SQL is handled by the SQL statement executor, or SQL engine. There is an overhead associated with each context switch between the two engines.
And that is why SQL is faster than PL/SQL. And that is what CM and MC are trying to explain you.
It's not just the context switch, it's also pulling the rowids into an array and then reading them back out again.
|
|
|
Re: FORALL BULK COLLECT [message #625461 is a reply to message #625450] |
Wed, 08 October 2014 06:35 |
ORAGENASHOK
Messages: 240 Registered: June 2006 Location: Chennai
|
Senior Member |
|
|
@ Lalit - I agree we have two engine for SQL and PLSQL and i agree CM and MC points too.Just went through some doc on bulk delete with normal one.
But below is the single delete stmt which i have used to delete the duplicates as i don't have any priviledges to drop the table and rename as its live table to the user.
delete from wkly_service_agg
where rowid not in
(select min(rowid)
from wkly_service_agg
where trunc(report_date) = trunc(to_date('22/08/2014','dd/mm/yyyy'))
group by report_date,week_num,service_group_key,p_pro_key, b_pro_key,
b_sd_key, v_prom_key, t_prot_key,
ni_flg, v_promo_key, service_type_id, subscode_key,
source_system_id,s_prot_key, ENABLED_PLATFORM,
PROMO_KEY,LONG_TERM_DISCOUNT,SPECIAL_OFFER_DISCOUNT,
SPORTS_RELIEF_PROD_KEY,HD_SD,FVA_FLG,BASIS_PRODUCT_KEY,
VOLUME_OF_SERVICE,FL_F_ELIGIBILITY,FL_SOURCE,B_CONTRACT_IND,
B_CONTRACT_REMAINING_KEY,D_MODEL_ID,V_CONTRACT_IND,V_CONTRACT_REMAINING_KEY,
V_CONTRACT_IND,V_CONTRACT_REMAINING_KEY,MID_TIER_DISCOUNT,DISCOUNT_METHOD,
M_PROMO_KEY,REL_DISC_S_KEY)
|
|
|
Re: FORALL BULK COLLECT [message #625471 is a reply to message #625461] |
Wed, 08 October 2014 08:25 |
joy_division
Messages: 4963 Registered: February 2005 Location: East Coast USA
|
Senior Member |
|
|
ORAGENASHOK wrote on Wed, 08 October 2014 07:35
where trunc(report_date) = trunc(to_date('22/08/2014','dd/mm/yyyy'))
the trunc on the right side is unnecessary.
If you have an index on report_date, you have just bypassed it with the trunc on the left side (unless you have a function based index). a between operator would have been better.
[Updated on: Wed, 08 October 2014 08:25] Report message to a moderator
|
|
|