Collect(distinct X))
I have a query that uses the COLLECT() aggregate function. Each item should appear only once in the output (no matter how many rows it's in). I'm running this in two different instances. It works fine in one, which is running "Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Production". In another, which is running "Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production", the "DISTINCT" is being ignored, and items appear multiple times.
My actual query is a big messy thing, but this (much smaller) example shows what I mean:
create table stuff (type varchar2(20), item varchar2(20), price number);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'beans', 0.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'bacon', 2.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'spam', 1.99);
insert into stuff (type, item, price) values ('food', 'eggs', 3.99);
insert into stuff (type, item, price) values ('clothes', 'shirt', 20);
insert into stuff (type, item, price) values ('electronics', 'camera', 100);
insert into stuff (type, item, price) values ('electronics', 'computer', 600);
select type, collect(distinct item), max(price), min(price)
from stuff
group by type;
drop table stuff;Here's the (correct) result from the 10.2.0.2.0 instance:
clothes
SYSTPYAAXsG1rAW7gQFuAjIUptg==('shirt')
20 20
electronics
SYSTPYAAXsG1rAW7gQFuAjIUptg==('camera', 'computer')
600 100
food
SYSTPYAAXsG1rAW7gQFuAjIUptg==('bacon', 'beans', 'eggs', 'spam')
3.99 .99. . . but here's the nasty failure from 10.2.0.3.0:
clothes
SYSTPYAAQJBD4LhDgQAB/AQBWTg==('shirt')
20 20
electronics
SYSTPYAAQJBD4LhDgQAB/AQBWTg==('camera', 'computer')
600 100
food
SYSTPYAAQJBD4LhDgQAB/AQBWTg==('spam', 'spam', 'spam', 'spam', 'spam', 'bacon', 'spam', 'eggs', 'spam', 'spam', 'spam', 'beans')
3.99 .99Thanks in advance for any insights!
-- John
Edited by: JohnI on Jan 8, 2009 4:48 PM
Funny, but I did not see any evidence that collect(distict X) should work at all.
In the doc: (http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions001.htm#sthref962)
"Many (but not all) aggregate functions that take a single argument accept these clauses:
* DISTINCT causes an aggregate function to consider only distinct values of the argument expression.
And then when you look at the functions themselves - the description of "sum" or "avg" shows that usage of distinct is possible, but the description of "collect" does not.
In any case, it looks like a bug that can be reported to Metalink.
BTW. 11.1.0.6 behaves just like 10.2.0.3
Edited by: Chen Shapira on Jan 8, 2009 2:29 PM
Similar Messages
-
DISTINCT on object type collection not working with GROUP BY
Hello,
I have an object type with collection defined as:
create or replace type individu_ot as object (
numero_dossier number(10),
code_utilisateur varchar2(8 char),
nom varchar2(25 char),
prenom varchar2(25 char),
map member function individu_map return number
create or replace type body individu_ot is
map member function individu_map return number
is
begin
return SELF.numero_dossier;
end individu_map;
end;
create or replace type individu_ntt is table of individu_ot
/When I use it in simple SQL without any aggregation, the distinct keyword works well and returns me the distinct entry of my object type in the collection:
SQL> select cast(collect(distinct individu_ot(indivmc.numero_dossier, indivmc.idul, indivmc.nom, indivmc.prenom)) as individu_ntt) as distinct_list
from site_section_cours sisc
inner join enseignant_section_mc ensemc
on sisc.code_session = ensemc.code_session and
sisc.numero_reference_section_cours = ensemc.numero_reference_section_cours
inner join individu_mc indivmc
on ensemc.numero_dossier_pidm = indivmc.numero_dossier
where sisc.seq_site_cours = 6
DISTINCT_LIST(NUMERO_DOSSIER,CODE_UTILISATEUR,NOM,PRENOM)
INDIVIDU_NTT(INDIVIDU_OT(15,PROF5,Amidala,Padmé))
1 row selected.However in SQL with broader selection with group by, the distinct isn't working anymore.
SQL> select *
from (
select sisc.seq_site_cours,
cast(collect(distinct individu_ot(indivmc.numero_dossier, indivmc.idul, indivmc.nom, indivmc.prenom)) as individu_ntt) as distinct_list
from site_section_cours sisc
inner join enseignant_section_mc ensemc
on sisc.code_session = ensemc.code_session and
sisc.numero_reference_section_cours = ensemc.numero_reference_section_cours
inner join individu_mc indivmc
on ensemc.numero_dossier_pidm = indivmc.numero_dossier
group by sisc.seq_site_cours
where seq_site_cours = 6
SEQ_SITE_COURS DISTINCT_LIST(NUMERO_DOSSIER,CODE_UTILISATEUR,NOM,PRENOM)
6 INDIVIDU_NTT(INDIVIDU_OT(15,PROF5,Amidala,Padmé),INDIVIDU_OT(15,PROF5,Amidala,Padmé),INDIVIDU_OT(15,PROF5,Amidala,Padmé),INDIVIDU_OT(15,PROF5,Amidala,Padmé),INDIVIDU_OT(15,PROF5,Amidala,Padmé))
1 row selected.there is case where I need to return more than one collections, with distinct entries in it.
Is there something I am missing?
Thanks
BrunoNot a bug, rather an undocumented feature.
Here are some alternatives you might want to test :
1) Using the SET operator to eliminate duplicates :
SELECT sisc.seq_site_cours,
set(
cast(
collect(individu_ot(indivmc.numero_dossier, indivmc.idul, indivmc.nom, indivmc.prenom))
as individu_ntt
) as distinct_list
FROM site_section_cours sisc
INNER JOIN enseignant_section_mc ensemc
ON sisc.code_session = ensemc.code_session
AND sisc.numero_reference_section_cours = ensemc.numero_reference_section_cours
INNER JOIN individu_mc indivmc
ON ensemc.numero_dossier_pidm = indivmc.numero_dossier
GROUP BY sisc.seq_site_cours
;2) Using MULTISET with a subquery
SELECT sisc.seq_site_cours,
CAST(
MULTISET(
SELECT distinct
indivmc.numero_dossier, indivmc.idul, indivmc.nom, indivmc.prenom
FROM enseignant_section_mc ensemc
INNER JOIN individu_mc indivmc
ON ensemc.numero_dossier_pidm = indivmc.numero_dossier
WHERE sisc.code_session = ensemc.code_session
AND sisc.numero_reference_section_cours = ensemc.numero_reference_section_cours
AS individu_ntt
) AS distinct_list
FROM site_section_cours sisc
; -
The COLLECT aggregate function
Hi,
Need some help understanding the COLLECT aggregate function.
My requirement is to concatenate all Varchar2 strings in a column into a single Varchar2 string...
The follwing thread seems somewhat relevant to the requirement....
collect(distinct X))
Thanks.The COLLECT docs specifically refer to working with nested tables. Are you working with one? If so post the DDL. There is a demo in Morgan's Library here: http://www.psoug.org/reference/collect_func.html#ccol
Personally this would be the last thing I'd thing of if the goal is as you state it. Well maybe not the last but far from the first.
I'd suggest looking at WM_CONCAT and then using TRANSLATE to replace the commas with '||'.
There is a demo of WM_CONCAT in Morgan's Library at www.psoug.org also.
But do check Tom Kyte's site: http://asktom.oracle.com
This is the type of thing Tom posts and his code is far better than mine. -
Not able to get distict values even after defining MAP MEMBER FUNCTION
Hi,
I am trying to get distinct values from a query to a table type. Please see the code below
CREATE OR REPLACE TYPE T_COPY_EVNT_DTL
IS
OBJECT
eventId VARCHAR2(100),
eventDescription VARCHAR2(100),
promoMonthDescription VARCHAR2(100),
promoStartDate VARCHAR2(100),
promoEndDate VARCHAR2(100),
PROMOCOSTSTARTDATE VARCHAR2(100) ,
MAP MEMBER FUNCTION sort_key
RETURN VARCHAR2 );
CREATE OR REPLACE TYPE BODY T_COPY_EVNT_DTL
AS
MAP MEMBER FUNCTION sort_key
RETURN VARCHAR2
IS
BEGIN
RETURN eventId ;
END;
END;
CREATE OR REPLACE TYPE T_EVENT_TABLE
IS
TABLE OF T_COPY_EVNT_DTL;
with event_data as (
select '1' event,'event1' event_desc,'monthdesc1' promo_month_desc ,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date,'01/02/2001' promo_cost_start_date from dual union all
select '1' event,'event1' event_desc ,'monthdesc1'promo_month_desc ,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date,'01/02/2001' promo_cost_start_date from dual union all
select '3' event,'desc3' event_desc ,'monthdesc3' promo_month_desc,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date,'01/02/2001' promo_cost_start_date from dual union all
select '2' event ,'desc2' event_desc ,'monthdesc2' promo_month_desc ,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date ,'01/02/2001' promo_cost_start_date from dual )
SELECT cast(collect(distinct t_copy_evnt_dtl(event,
event_desc,
promo_month_desc,
promo_start_date,
promo_end_date,
promo_cost_start_date) ORDER BY
event_desc,
promo_month_desc,
promo_start_date,
promo_end_date,
promo_cost_start_date) as t_event_table) from event_data;
result :
T_EVENT_TABLE('T_COPY_EVNT_DTL('2','desc2','monthdesc2','01/01/2001','01/01/2002','01/02/2001')',
'T_COPY_EVNT_DTL('3','desc3','monthdesc3','01/01/2001','01/01/2002','01/02/2001')',
'T_COPY_EVNT_DTL('1','event1','monthdesc1','01/01/2001','01/01/2002','01/02/2001')',
'T_COPY_EVNT_DTL('1','event1','monthdesc1','01/01/2001','01/01/2002','01/02/2001')')Please help me to find out the reason why it is not working...Remove the comma from T_COPY_EVNT_DTL TYPE.
ORA-22800 indicates invalid user-defined type.
PROMOCOSTSTARTDATE VARCHAR2(100) ,
MAP MEMBER FUNCTION sort_keyAnd it will be fine.
SQL> CREATE OR REPLACE TYPE T_COPY_EVNT_DTL
2 IS
3 OBJECT
4 (
5 eventId VARCHAR2(100),
6 eventDescription VARCHAR2(100),
7 promoMonthDescription VARCHAR2(100),
8 promoStartDate VARCHAR2(100),
9 promoEndDate VARCHAR2(100),
10 PROMOCOSTSTARTDATE VARCHAR2(100),
11 --,
12 MAP MEMBER FUNCTION sort_key
13 RETURN VARCHAR2 );
14 /
Type created
SQL>
SQL> CREATE OR REPLACE TYPE BODY T_COPY_EVNT_DTL
2 AS
3 MAP MEMBER FUNCTION sort_key
4 RETURN VARCHAR2
5 IS
6 BEGIN
7 RETURN eventId ;
8 END;
9 END;
10 /
Type body created
SQL>
SQL> CREATE OR REPLACE TYPE T_EVENT_TABLE
2 IS
3 TABLE OF T_COPY_EVNT_DTL;
4 /
Type created
SQL>
SQL> with event_data as (
2 select '1' event,'event1' event_desc,'monthdesc1' promo_month_desc ,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date,'01/02/2001' promo_cost_start_date from dual union all
3 select '1' event,'event1' event_desc ,'monthdesc1'promo_month_desc ,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date,'01/02/2001' promo_cost_start_date from dual union all
4 select '3' event,'desc3' event_desc ,'monthdesc3' promo_month_desc,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date,'01/02/2001' promo_cost_start_date from dual union all
5 select '2' event ,'desc2' event_desc ,'monthdesc2' promo_month_desc ,'01/01/2001' promo_start_date ,'01/01/2002' promo_end_date ,'01/02/2001' promo_cost_start_date from dual )
6 SELECT cast(collect(distinct t_copy_evnt_dtl(event,
7 event_desc,
8 promo_month_desc,
9 promo_start_date,
10 promo_end_date,
11 promo_cost_start_date) ORDER BY
12 event_desc,
13 promo_month_desc,
14 promo_start_date,
15 promo_end_date,
16 promo_cost_start_date) as t_event_table) from event_data;
CAST(COLLECT(DISTINCTT_COPY_EV
<Object> -
Want to create XML tag from the query
Here i want to create a xml output from the below code for the given P_repair_number can anyone help me for the code i have written
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
facing the above error when run from concurrent program
Procedure dfdfdf(p_repair_number number,
errbuf OUT VARCHAR2,
retcode OUT NUMBER) as
v_error_code NUMBER; -- error code
v_error_message VARCHAR2(255); -- error message
v_text_msg VARCHAR2(100);
cursor Rodetails(p_repair_number IN NUMBER) is
SELECT
dra.repair_number,
dra.repair_line_id,
items.concatenated_segments item_name,
items.description item_desc,
dra.inventory_item_id,
sr.incident_number sr_incident_number,
decode(dra.customer_product_id, '',dra.serial_number,cp.serial_number) serial_number,
ltrim(oeh.order_number) rma_number,
rstl.resource_name ro_owner_name,
fndl.meaning flow_status_name,
dra.status ro_status_code,
drtt.name repair_type_name,
dra.problem_description,
dra.promise_date,
rgtl.group_name repair_org_name,
decode(dra.customer_product_id, '',dra.item_revision,cp.inventory_revision) revision,
cp.lot_number,
dra.unit_of_measure uom_code,
uom.unit_of_measure_tl uom_name,
dra.quantity,
cp.instance_number ib_instance_number,
plkup.meaning ro_priority_meaning
FROM
csd_repairs dra,
csd_repair_types_tl drtt,
cs_incidents_all_b sr,
csi_item_instances cp,
fnd_lookups fndl,
csd_flow_statuses_b fsb,
mtl_system_items_kfv items,
mtl_units_of_measure_tl uom,
jtf_rs_resource_extns_tl rstl,
jtf_rs_groups_tl rgtl,
oe_order_headers_all oeh,
cs_estimate_details edt,
csd_product_transactions txns,
fnd_lookups plkup
WHERE dra.repair_type_id = drtt.repair_type_id
AND drtt.language = userenv('LANG')
AND dra.repair_mode = 'WIP'
AND dra.incident_id = sr.incident_id
AND dra.CUSTOMER_PRODUCT_ID = cp.INSTANCE_ID(+)
AND dra.flow_status_id = fsb.flow_status_id
AND fsb.flow_status_code = fndl.lookup_code
AND fndl.lookup_type = 'CSD_REPAIR_FLOW_STATUS'
AND dra.inventory_item_id = items.inventory_item_id
AND dra.unit_of_measure = uom.uom_code
AND uom.language = userenv('LANG')
AND dra.resource_id = rstl.resource_id (+)
AND rstl.category (+) = 'EMPLOYEE'
AND rstl.language (+) = userenv('LANG')
AND dra.owning_organization_id = rgtl.group_id (+)
AND rgtl.language (+) = userenv('LANG')
AND dra.repair_line_id = txns.repair_line_id
AND txns.estimate_detail_id = edt.estimate_detail_id
AND edt.order_header_id = oeh.header_id
AND edt.line_category_code = 'RETURN'
AND dra.currency_code = oeh.transactional_curr_code
AND dra.ro_priority_code = plkup.lookup_code(+)
AND plkup.lookup_type(+) = 'CSD_RO_PRIORITY'
AND items.organization_id = cs_std.get_item_valdn_orgzn_id
AND dra.repair_number=p_repair_number
AND rownum <50;
begin
errbuf := NULL;
retcode := 0;
SAVEPOINT Create_external_orders;
--retcode := FND_API.G_RET_STS_SUCCESS;
IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level) THEN
fnd_log.STRING (fnd_log.level_procedure, 'CSD.PLSQL.XXTNT_CSD_CREATEORDER.SUBMIT_CREATE_ORDER.BEGIN', 'Enter - PrintTraveller');
END IF;
--FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<?xml version="1.0"?>');
--FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REPAIR_ORDER>');
FOR v_rodetails IN Rodetails(p_repair_number)
LOOP
/*For each record create a group tag <G_RODETAILS> at the start*/
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<?xml version="1.0"?>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REPAIR_ORDER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<G_RODETAILS>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REPAIR_NUMBER>' || v_rodetails.repair_number ||
'</REPAIR_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REPAIR_LINE_ID>' || v_rodetails.repair_line_id
|| '</REPAIR_LINE_ID>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ITEM_NAME>' || v_rodetails.ITEM_NAME
||'</ITEM_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<ITEM_DESC>' || v_rodetails.ITEM_DESC
|| '</ITEM_DESC>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SR_INCIDENT_NUMBER>' || v_rodetails.SR_INCIDENT_NUMBER ||
'</SR_INCIDENT_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<SERIAL_NUMBER>' ||v_rodetails.SERIAL_NUMBER
||'</SERIAL_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<RMA_NUMBER>' || v_rodetails.RMA_NUMBER
|| '</RMA_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<RO_OWNER_NAME>' ||v_rodetails.RO_OWNER_NAME ||
'</RO_OWNER_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<FLOW_STATUS_NAME>' || v_rodetails.FLOW_STATUS_NAME
||'</FLOW_STATUS_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<RO_STATUS_CODE>' || v_rodetails.RO_STATUS_CODE
|| '</RO_STATUS_CODE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REPAIR_TYPE_NAME>' || v_rodetails.REPAIR_TYPE_NAME ||
'</REPAIR_TYPE_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<PROBLEM_DESCRIPTION>' || v_rodetails.PROBLEM_DESCRIPTION
||'</PROBLEM_DESCRIPTION>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<PROMISE_DATE>' || v_rodetails.PROMISE_DATE
|| '</PROMISE_DATE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<RO_OWNER_NAME>' || v_rodetails.RO_OWNER_NAME ||
'</RO_OWNER_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REPAIR_ORG_NAME>' || v_rodetails.REPAIR_ORG_NAME
||'</REPAIR_ORG_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<RO_STATUS_CODE>' || v_rodetails.RO_STATUS_CODE
|| '</RO_STATUS_CODE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<REVISION>' || v_rodetails.REVISION ||
'</REVISION>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<LOT_NUMBER>' || v_rodetails.LOT_NUMBER
||'</LOT_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<UOM_CODE>' || v_rodetails.UOM_CODE
|| '</UOM_CODE>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<UOM_NAME>' ||v_rodetails.UOM_NAME ||
'</UOM_NAME>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<QUANTITY>' || v_rodetails.QUANTITY
||'</QUANTITY>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<IB_INSTANCE_NUMBER>' || v_rodetails.IB_INSTANCE_NUMBER
|| '</IB_INSTANCE_NUMBER>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'<RO_PRIORITY_MEANING>' || v_rodetails.RO_PRIORITY_MEANING ||
'</RO_PRIORITY_MEANING>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'</G_RODETAILS>');
FND_FILE.PUT_LINE(FND_FILE.OUTPUT,'</REPAIR_ORDER>');
END LOOP;
IF(retcode != FND_API.G_RET_STS_SUCCESS) THEN
RAISE FND_API.G_EXC_ERROR;
END IF;
IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level) THEN
fnd_log.STRING (fnd_log.level_statement, 'CSD.PLSQL.XXTNT_CSD_CREATEORDER.SUBMIT_CREATE_ORDER', ' In PrintTraveller');
END IF;
fnd_file.put_line(fnd_file.log, 'Successfully completed PrintTraveller');
EXCEPTION
|| Catch all error.
WHEN OTHERS THEN
ROLLBACK;
v_error_code := SQLCODE;
v_text_msg := 'Fatal Error, Oracle Error is: '
|| TO_CHAR (v_error_code, '99999');
fnd_file.put_line (fnd_file.log, v_text_msg);
v_error_message := SQLERRM;
fnd_file.put_line (fnd_file.log, v_error_message);
end dfdfdf;Edited by: user12053530 on Apr 19, 2010 5:54 AMHowever using SYS.ODCIVARCHAR2LIST makes sense if your query is a part of bigger processing (PL/SQL procedure or function) and you will do some processing depending on File_Type, like in this example (not compiled, could contain syntax errors):
DECLARE
l_stid VARCHAR2(10);
l_address VARCHAR2(30);
l_File_Type_tab SYS.ODCIVARCHAR2LIST;
cur_cursor IS SELECT STID,
ADDRESS,
CAST(COLLECT(DISTINCT File_Type) AS SYS.ODCIVARCHAR2LIST) AS File_Type
FROM (
SELECT STID,
ADDRESS,
File_Type
FROM DUMMY
GROUP BY STID, ADDRESS;
BEGIN
OPEN cur_cursor;
<<main_loop>>
WHILE (1=1) LOOP
FETCH cur_cursor INTO l_stid, l_address, l_File_Type_tab;
EXIT WHEN cur_cursor%NOTFOUND;
-- Now do processing for each File_Type in l_File_Type_tab;
<<each_file_type>>
FOR i IN l_File_Type_tab.FIRST .. l_File_Type_tab.LAST LOOP
-- for example:
-- IF l_File_Type_tab(i) = 'SALES'
-- THEN
-- do_something(l_stid, l_address);
-- ELSIF l_File_Type_tab(i) = 'TRANSFER'
-- THEN
-- do_something_else(l_stid, l_address);
-- ELSE
-- do_something_default(l_stid, l_address);
-- END IF;
END LOOP each_file_type;
END LOOP main_loop;
CLOSE cur_cursor;
END; -
I'm trying to implement a mapping for some columns in what Kimball calls a "Junk Dimension." There are 25 columns in the dimension with cardinality's ranging from 2 to 10. There are 100,000,000 possible values, but only around 100,000 actually exist in the data set. I'd rather just populate the table with the 100,000 rows.
Here's a refernece to Kimball's discussion of this:
http://www.kimballgroup.com/html/designtipsPDF/DesignTips2003/KimballDT48DeClutter.pdf
Is the only way to do this in OWB to use a deduplicator (DISTINCT)?
If I have 2 dimensions like this, plus the fact table, am I going to fully scan the source table 3 times, once for each of the 2 distinct queries, and once for mapping into the fact table?
Is there a more efficient solution?With Statuses dimension everything is clear its classic junk dimension sourced from distinct values of different status fields.
About Bands dimension Have you explicitly define (somewhere) bands for every value you are expecting to classify? If so, creating this dimension is much straightforward as previous to join source table with band definition tables and collect distinct combinations of every band id into band junk.
If you are going to create bands implicitly (or dynamically by applying expression like trunc(x,-2) ), approach may be the same. Just take additional care to not archive useless banding remember that there are recommendation in statistics regarding optimal number of bands depending on number of measures (records) and magnitude of values (from min to max value).
I would not advise you to apply this function lookup approach. It will perform very poor on large dataset (because SQL <-> PLSQL context switching and additional exception handling if key not found). Better try to browse source data during stage operation, find new key combinations for junk dimensions and load them. After that use simple join / lookup to get dimension key.
Sergey -
How to get distinct values from a list and display in a ListView webpart.
Hi,
I have a requirement in which I need to pull unique/distinct values from a custom list and then display it via a listview webpart. Can any one suggest how this can be done.
If possible please share the CAMEL query to fetch distinct values from a custom list.
Thanks,
AnkitHi Ankit,
Is there any particular reason that the values need to be shown in a list view web part? Are you going to use that web part for filtering via web part connections?
I ask because the enterprise site collection features include the SharePoint List Filter web part, which may accomplish what you're looking for.
If you just need to display the values in a grid view, you might have more luck with the JavaScript Client Object Model. Try putting the following in a text file:
<style>
.CustomTableClass{display:table;table-layout:fixed}
.CustomRowClass{display:table-row;}
</style>
<div id="distinct_values_div" class="CustomTableClass">
<img src="/_layouts/loading.gif" />
</div>
<script language="JavaScript" type="text/JavaScript">
var siteUrl = '/sitecollection/web'; //use the actual subsite URL here
var listName = 'mylist'; // use the actual list name here
var field = "Title" // use the actual field you want to display here
var divToUpdate = document.getElementById("distinct_values_div");
var rowClass = "CustomRowClass";
ExecuteOrDelayUntilScriptLoaded(function(){
var clientContext = new SP.ClientContext(siteUrl);
var web = clientContext.get_web();
var lists = web.get_lists();
var list = lists.getByTitle(listName);
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml('<View><Query></Query><RowLimit>500</RowLimit></View>');
this.collListItem = list.getItems(camlQuery);
clientContext.load(collListItem,"Include ("+field+")");
clientContext.executeQueryAsync(
Function.createDelegate(this, this.onQuerySucceeded),
Function.createDelegate(this, this.onQueryFailed));
},"sp.js");
function onQueryFailed(sender, args){
divToUpdate.innerHTML = 'Unable to retrieve values: '+args.get_message());
function onQuerySucceeded(sender, args){
var allValues = [];
var listItemEnumerator = collListItem.getEnumerator();
divToUpdate.innerHTML = "";
while(listItemEnumerator.moveNext()){
var listItem = listItemEnumerator.get_current();
if(!containsString(allValues,listItem.get_item(field)){
var value = listItem.get_item(field);
allValues.push(value);
var newDiv = document.createElement("div");
newDiv.className = rowClass;
newDiv.innerHTML = value;
divToUpdate.appendChild(newDiv);
function containsString(strArray, text){
var contains = false;
for (var i=0; i<strArray.length; i++){
if(strArray[i]==text){contains = true; break;}
return contains;
</script>
Upload the text file to a library on the site, then add a content editor web part to a page where you want the distinct values to appear. In the content editor web part's properties, edit the Content Link so that it links directly to the text file. This
will cause the JavaScript to run on the page. -
"How to get distinct values of sharepoint column using SSRS"
Hi,
I have integrated sharepoint list data to SQL Server reporting services. I am using the below to query sharepoint list data using sql reporting services.
<Query>
<SoapAction>http://schemas.microsoft.com/sharepoint/soap/GetListItems</SoapAction>
<Method Namespace="http://schemas.microsoft.com/sharepoint/soap/" Name="GetListItems">
<Parameters>
<Parameter Name="listName">
<DefaultValue>{GUID of list}</DefaultValue>
</Parameter>
<Parameter Name="viewName">
<DefaultValue>{GUID of listview}</DefaultValue>
</Parameter>
<Parameter Name="rowLimit">
<DefaultValue>9999</DefaultValue>
</Parameter>
</Parameters>
</Method>
<ElementPath IgnoreNamespaces="True">*</ElementPath>
</Query>
By using this query, I am getting a dataset which includes all the columns of sharepoint list. Among these columns, I wanted to display only 2 columns (i.e Region and Sales type) using chart. I have created a Region parameter but when I click preview, the drop down box is giving me all the repeatative values of region like RG1,RG1,RG1,RG2,RG2,RG2,RG2,RG3.......... I wanted to display only distinct values of Region parameter so that whenever end user select region from the parameter drop down, it will display the respective value of Sales type column.
Also when I select only RG1 parameter, it is giving me a chart including the sales type of all the Regions. (it should display me only the sales type of RG1) How can I link these 2 columns so that they will display the values respectively.
I would really appreciate if anyone can help me out with this.
Thanks,
Sam.Hi Sam,
By code, the CAML language doesn’t have any reserved word (or tag) to set this particular filter to remove duplicate results.
In this case, we could use the custom code to get distinct records.
Here are the detailed steps:
1. Create a hidden parameter that gets all the records in one field.
Note: Please create another dataset that is same of the main dataset. This dataset is used for the parameter.
2. Create a function that used to remove the duplicate records.
Here is the code:
Public Shared Function RemoveDups(ByVal items As String) As String
Dim noDups As New System.Collections.ArrayList()
Dim SpStr
SpStr = Split(items ,",")
For i As Integer=0 To Ubound(Spstr)
If Not noDups.Contains(SpStr(i).Trim()) Then
noDups.Add(SpStr(i).Trim())
End If
Next
Dim uniqueItems As String() = New String(noDups.Count-1){}
noDups.CopyTo(uniqueItems)
Return String.Join(",", uniqueItems)
End Function
3. Create another parameter that will be used for filtering the maindata.
Please set the available value to be =Split(Code.RemoveDups(JOIN(Parameters!ISSUE_STATUS_TEMP.Value, ",")), ",")
And the default value to be the value you what such as the first value:
=Split(Code.RemoveDups(JOIN(Parameters!ISSUE_STATUS_TEMP.Value, ",")), ",").(0)
4. Go to the main dataset. Open the property window of this dataset.
5. In the “Filters” tab, set the filter to be:
Expression: <The field to be filter>
Operator: =
Value: =Parameters!Region.Value
The parameter “Region” should be the parameter we created in the step3.
Now, we should get distinct values of SharePoint columns.
If there is anything unclear, please feel free to ask.
Thanks,
Jin
Jin Chen - MSFT -
Get distinct values from plsql array
Hi,
I have declared a variable as below in plsql proc.
type t_itemid is table of varchar2(10);
inserted set of items in to this using a program
now i want distinct values from that array how can i get it.I am using 9i so i cannot use set operator and more over my problem is that i am declaring the variable inside the plsql block . when i tried i am getting the below errors:
SQL> r
1 declare
2 type t_type is table of varchar2(10);
3 v_type t_type;
4 begin
5 v_type := t_type('toys','story','good','good','toys','story','dupe','dupe');
6 for i in (select column_value from table(v_type)) loop
7 dbms_output.put_line(i.column_value);
8 end loop;
9* end;
for i in (select column_value from table(v_type)) loop
ERROR at line 6:
ORA-06550: line 6, column 41:
PLS-00642: local collection types not allowed in SQL statements
ORA-06550: line 6, column 35:
PL/SQL: ORA-22905: cannot access rows from a non-nested table item
ORA-06550: line 6, column 10:
PL/SQL: SQL Statement ignored
ORA-06550: line 7, column 22:
PLS-00364: loop index variable 'I' use is invalid
ORA-06550: line 7, column 1:
PL/SQL: Statement ignored -
Any way to use cursor values inside other cursor by bulk collect?
hi,
Is there any way to use cursor get_tables value insdide loop get column if i am using bulk collect in both cursors?
I tried a lot but i am nt able to do it.kindly help...
create or replace procedure MULTIPLE_CURSORS_PROC is
v_owner varchar2(40);
v_table_name varchar2(40);
v_column_name varchar2(100);
cursor get_tables is
select distinct tbl.owner, tbl.table_name
from all_tables tbl
where tbl.owner = 'SYSTEM';
cursor get_columns is
select distinct col.column_name
from all_tab_columns col
where col.owner = v_owner
and col.table_name = v_table_name;
begin
open get_tables;
loop
fetch get_tables into v_owner, v_table_name;
open get_columns;
loop
fetch get_columns into v_column_name;
end loop;
close get_columns;
end loop;
close get_tables;
end ;hi there
Refer this
CREATE OR REPLACE PROCEDURE MULTIPLE_CURSORS_PROC
IS
TYPE scol IS VARRAY (10000) OF VARCHAR2 (32767);
v_table_name scol;
v_column_name scol;
TYPE curtyp IS REF CURSOR;
get_columns curtyp;
CURSOR get_tables
IS
SELECT DISTINCT tbl.table_name
FROM all_tables tbl
WHERE tbl.owner = 'SYSTEM';
BEGIN
OPEN get_tables;
LOOP
FETCH get_tables BULK COLLECT INTO v_table_name;
FOR indx IN v_table_name.FIRST .. v_table_name.LAST
LOOP
SELECT DISTINCT col.column_name
BULK COLLECT
INTO v_column_name
FROM all_tab_columns col
WHERE col.table_name = v_table_name (indx);
FOR ind IN v_column_name.FIRST .. v_column_name.LAST
LOOP
DBMS_OUTPUT.put_line (v_column_name (ind));
END LOOP;
END LOOP;
EXIT WHEN get_tables%NOTFOUND;
END LOOP;
CLOSE get_tables;
END MULTIPLE_CURSORS_PROC;regards
Hitesh -
SCCM Report for Applicable and Installed Updates Collection Wise
Hi All, I was looking for a report on Applicable and Installed Updates Collection Wise and got this below query on the Internet and want to create a SCCM report with this below query. How to make this query working in SCCM report?
Do I need to add prompts, if yes please guide me on adding prompts.
SELECT
DISTINCT
SYS.Name0
AS [Server Name], SIS.SMS_Installed_Sites0 AS [Site Code], UCS.Status AS [Patch Status Code],
CASE WHEN UCS.Status = '2' THEN 'Applicable' WHEN UCS.Status = '3' THEN 'Installed' ELSE '' END AS 'Patch Status', UI.BulletinID AS [Bulletin ID],
UI
.ArticleID AS [Article ID], UI.
Title
FROM
v_R_System AS SYS LEFT OUTER
JOIN
v_Update_ComplianceStatusAll
AS UCS ON SYS.ResourceID = UCS.ResourceID INNER
JOIN
v_UpdateInfo
AS UI ON UCS.CI_ID = UI.CI_ID INNER
JOIN
v_RA_System_SMSInstalledSites
AS SIS ON SYS.ResourceID = SIS.
ResourceID
WHERE
(UCS.Status IN ('2', '3')) AND (UI.ArticleID IN ('972270', '974392', '973904', '969947')) AND (SYS.Name0
IN
(SELECT DISTINCT v_FullCollectionMembership.
Name
FROM v_FullCollectionMembership INNER
JOIN
v_R_System
ON v_R_System.ResourceID = v_FullCollectionMembership.ResourceID AND v_R_System.Active0 = 1 AND
v_FullCollectionMembership
.CollectionID IN ('Collection ID'
ORDER
BY
[Patch Status Code]Yes it can be done and please run the query which i have shared in the thread
I again pasted the query for you below..
SELECT DISTINCT
SYS.Name0 AS [Server Name], CASE WHEN UCS.Status = '2' THEN 'Applicable' WHEN UCS.Status = '3' THEN 'Installed' ELSE '' END AS 'Patch Status',
UI.BulletinID AS [Bulletin ID], UI.ArticleID AS [Article ID], UI.Title
FROM v_R_System AS SYS LEFT OUTER JOIN
v_Update_ComplianceStatusAll
AS UCS ON SYS.ResourceID = UCS.ResourceID INNER JOIN
v_UpdateInfo AS UI ON UCS.CI_ID
= UI.CI_ID
WHERE (UCS.Status IN ('2', '3')) AND (SYS.Name0 IN (SELECT DISTINCT v_FullCollectionMembership.Name
FROM v_FullCollectionMembership INNER JOIN
v_R_System ON v_R_System.ResourceID = v_FullCollectionMembership.ResourceID AND v_R_System.Active0 = 1 AND
v_FullCollectionMembership.CollectionID
IN ('XXX00000')))
Kamala kannan.c| Please remember to click “Mark as Answer” or Vote as Helpful if its helpful for you. |Disclaimer: This posting is provided with no warranties and confers no rights -
Patch compliance report for all machines in collection
Good day to all,
We are trying to create a report in SCCM 2012 that will show us all missing updates on all computers in collection. But we would like to display in this report only patches which are really targeted to the machines in collection. Let me explain.
We have multiple deployment groups for patching (OSD, Servers, Client, Test waves...) and current issue we have with all build in reports is that you have to either select one of these deployments and then select a collections - but this will give you only
status for current group of patches, for another one you have to select different one. And if there is a report where you have to select only collection the it will show all updates which are in deployment (this is not nice as for OSD we are putting some extra
patches to the image and then these patches are shown as missing on all machines - but they will stay that way as we are not deploying them...yet). The ideal report for us will be to select the collection and then show all missing patches that are targeted
to that collection. This was accomplished by this query:
SELECT
vRS.NetBios_Name0 AS 'Hostname',
Count(DISTINCT vUI.ArticleID) AS 'Missing Patches'
FROM v_UpdateComplianceStatus vUCS
INNER JOIN v_CIRelation vCIR ON vUCS.CI_ID = vCIR.ToCIID
LEFT JOIN v_AuthListInfo vALI ON vALI.CI_ID = vCIR.FromCIID
INNER JOIN v_UpdateInfo vUI ON vUCS.CI_ID = vUI.CI_ID
LEFT JOIN v_R_System vRS ON vUCS.ResourceID = vRS.ResourceID
WHERE vUCS.ResourceID IN (SELECT vFCM.ResourceID FROM v_FullCollectionMembership vFCM WHERE vFCM.CollectionID = 'CAS00296')
AND vUCS.Status = '2'
AND vALI.Title LIKE 'SWU Workstations ENG%'
GROUP BY vRS.NetBios_Name0
ORDER BY 2
However, if we would like to add more columns, like Reboot Pending, Failed, Installed, Not Needed... then the report will start to show incorrect data, e.g. for machine which is fully patched and according to "Programs and Features - Show installed
updates" have 235 patches installed it will show only 198 patches installed and 10 missing.
It have something to do with JOINs between tables but we are at the end of ideas how to proceed further (we already checked the official documentation for SQL tables in new SCCM).
Have any of you created a report like this? I tried to Bing/Google for hours but most of the reports are for SCCM 2007 and showing incorrect data.Almost all SU reports created for CM07, still apply to CM12.
http://www.enhansoft.com/ -
Can I use Bulk Collect results as input parameter for another cursor
MUSIC ==> remote MUSIC_DB database, MUSIC table has 60 million rows
PRICE_DATA ==> remote PRICING_DB database, PRICE_DATE table has 1 billion rows
These two table once existed in same database, but size of database exceeded available hardware size and hardware budget, so the PRICE_DATA table was moved to another Oracle database. I need to create a single report that combines data from both of these tables, and a distributed join with DRIVING_SITE hint will not work because the size of both table is too large to push to one DRIVING_SITE location, so I wrote this PLSQL block to process in small blocks.
QUESTION: how can use bulk collect from one cursor and pass that bulk collected information as input to second cursor without specifically listing each cell of the PLSQL bulk collection? See sample pseudo-code below, I am trying to determine more efficient way to code than hard-coding 100 parameter names into 2nd cursor.
NOTE: below is truly pseudo-code, I had to change the names of everything to adhere to NDA, but below works and is fast enough for my purposes, but if I want to change from 100 input parameters to 200, I have to add more hard-coded values. There has got to be a better way.
DECLARE
-- define cursor that retrieves distinct SONG_IDs from MUSIC table in remote music database
CURSOR C_CURRENT_MUSIC
IS
select distinct SONG_ID
from MUSIC@MUSIC_DB
where PRODUCTION_RELEASE=1
/* define a parameterized cursor that accepts 100 SONG_IDs and retrieves
required pricing information
CURSOR C_get_music_price_data
P_SONG_ID_001 NUMBER, P_SONG_ID_002 NUMBER, P_SONG_ID_003 NUMBER, P_SONG_ID_004 NUMBER, P_SONG_ID_005 NUMBER, P_SONG_ID_006 NUMBER, P_SONG_ID_007 NUMBER, P_SONG_ID_008 NUMBER, P_SONG_ID_009 NUMBER, P_SONG_ID_010 NUMBER,
P_SONG_ID_011 NUMBER, P_SONG_ID_012 NUMBER, P_SONG_ID_013 NUMBER, P_SONG_ID_014 NUMBER, P_SONG_ID_015 NUMBER, P_SONG_ID_016 NUMBER, P_SONG_ID_017 NUMBER, P_SONG_ID_018 NUMBER, P_SONG_ID_019 NUMBER, P_SONG_ID_020 NUMBER,
P_SONG_ID_021 NUMBER, P_SONG_ID_022 NUMBER, P_SONG_ID_023 NUMBER, P_SONG_ID_024 NUMBER, P_SONG_ID_025 NUMBER, P_SONG_ID_026 NUMBER, P_SONG_ID_027 NUMBER, P_SONG_ID_028 NUMBER, P_SONG_ID_029 NUMBER, P_SONG_ID_030 NUMBER,
P_SONG_ID_031 NUMBER, P_SONG_ID_032 NUMBER, P_SONG_ID_033 NUMBER, P_SONG_ID_034 NUMBER, P_SONG_ID_035 NUMBER, P_SONG_ID_036 NUMBER, P_SONG_ID_037 NUMBER, P_SONG_ID_038 NUMBER, P_SONG_ID_039 NUMBER, P_SONG_ID_040 NUMBER,
P_SONG_ID_041 NUMBER, P_SONG_ID_042 NUMBER, P_SONG_ID_043 NUMBER, P_SONG_ID_044 NUMBER, P_SONG_ID_045 NUMBER, P_SONG_ID_046 NUMBER, P_SONG_ID_047 NUMBER, P_SONG_ID_048 NUMBER, P_SONG_ID_049 NUMBER, P_SONG_ID_050 NUMBER,
P_SONG_ID_051 NUMBER, P_SONG_ID_052 NUMBER, P_SONG_ID_053 NUMBER, P_SONG_ID_054 NUMBER, P_SONG_ID_055 NUMBER, P_SONG_ID_056 NUMBER, P_SONG_ID_057 NUMBER, P_SONG_ID_058 NUMBER, P_SONG_ID_059 NUMBER, P_SONG_ID_060 NUMBER,
P_SONG_ID_061 NUMBER, P_SONG_ID_062 NUMBER, P_SONG_ID_063 NUMBER, P_SONG_ID_064 NUMBER, P_SONG_ID_065 NUMBER, P_SONG_ID_066 NUMBER, P_SONG_ID_067 NUMBER, P_SONG_ID_068 NUMBER, P_SONG_ID_069 NUMBER, P_SONG_ID_070 NUMBER,
P_SONG_ID_071 NUMBER, P_SONG_ID_072 NUMBER, P_SONG_ID_073 NUMBER, P_SONG_ID_074 NUMBER, P_SONG_ID_075 NUMBER, P_SONG_ID_076 NUMBER, P_SONG_ID_077 NUMBER, P_SONG_ID_078 NUMBER, P_SONG_ID_079 NUMBER, P_SONG_ID_080 NUMBER,
P_SONG_ID_081 NUMBER, P_SONG_ID_082 NUMBER, P_SONG_ID_083 NUMBER, P_SONG_ID_084 NUMBER, P_SONG_ID_085 NUMBER, P_SONG_ID_086 NUMBER, P_SONG_ID_087 NUMBER, P_SONG_ID_088 NUMBER, P_SONG_ID_089 NUMBER, P_SONG_ID_090 NUMBER,
P_SONG_ID_091 NUMBER, P_SONG_ID_092 NUMBER, P_SONG_ID_093 NUMBER, P_SONG_ID_094 NUMBER, P_SONG_ID_095 NUMBER, P_SONG_ID_096 NUMBER, P_SONG_ID_097 NUMBER, P_SONG_ID_098 NUMBER, P_SONG_ID_099 NUMBER, P_SONG_ID_100 NUMBER
IS
select
from PRICE_DATA@PRICING_DB
where COUNTRY = 'USA'
and START_DATE <= sysdate
and END_DATE > sysdate
and vpc.SONG_ID IN
P_SONG_ID_001 ,P_SONG_ID_002 ,P_SONG_ID_003 ,P_SONG_ID_004 ,P_SONG_ID_005 ,P_SONG_ID_006 ,P_SONG_ID_007 ,P_SONG_ID_008 ,P_SONG_ID_009 ,P_SONG_ID_010,
P_SONG_ID_011 ,P_SONG_ID_012 ,P_SONG_ID_013 ,P_SONG_ID_014 ,P_SONG_ID_015 ,P_SONG_ID_016 ,P_SONG_ID_017 ,P_SONG_ID_018 ,P_SONG_ID_019 ,P_SONG_ID_020,
P_SONG_ID_021 ,P_SONG_ID_022 ,P_SONG_ID_023 ,P_SONG_ID_024 ,P_SONG_ID_025 ,P_SONG_ID_026 ,P_SONG_ID_027 ,P_SONG_ID_028 ,P_SONG_ID_029 ,P_SONG_ID_030,
P_SONG_ID_031 ,P_SONG_ID_032 ,P_SONG_ID_033 ,P_SONG_ID_034 ,P_SONG_ID_035 ,P_SONG_ID_036 ,P_SONG_ID_037 ,P_SONG_ID_038 ,P_SONG_ID_039 ,P_SONG_ID_040,
P_SONG_ID_041 ,P_SONG_ID_042 ,P_SONG_ID_043 ,P_SONG_ID_044 ,P_SONG_ID_045 ,P_SONG_ID_046 ,P_SONG_ID_047 ,P_SONG_ID_048 ,P_SONG_ID_049 ,P_SONG_ID_050,
P_SONG_ID_051 ,P_SONG_ID_052 ,P_SONG_ID_053 ,P_SONG_ID_054 ,P_SONG_ID_055 ,P_SONG_ID_056 ,P_SONG_ID_057 ,P_SONG_ID_058 ,P_SONG_ID_059 ,P_SONG_ID_060,
P_SONG_ID_061 ,P_SONG_ID_062 ,P_SONG_ID_063 ,P_SONG_ID_064 ,P_SONG_ID_065 ,P_SONG_ID_066 ,P_SONG_ID_067 ,P_SONG_ID_068 ,P_SONG_ID_069 ,P_SONG_ID_070,
P_SONG_ID_071 ,P_SONG_ID_072 ,P_SONG_ID_073 ,P_SONG_ID_074 ,P_SONG_ID_075 ,P_SONG_ID_076 ,P_SONG_ID_077 ,P_SONG_ID_078 ,P_SONG_ID_079 ,P_SONG_ID_080,
P_SONG_ID_081 ,P_SONG_ID_082 ,P_SONG_ID_083 ,P_SONG_ID_084 ,P_SONG_ID_085 ,P_SONG_ID_086 ,P_SONG_ID_087 ,P_SONG_ID_088 ,P_SONG_ID_089 ,P_SONG_ID_090,
P_SONG_ID_091 ,P_SONG_ID_092 ,P_SONG_ID_093 ,P_SONG_ID_094 ,P_SONG_ID_095 ,P_SONG_ID_096 ,P_SONG_ID_097 ,P_SONG_ID_098 ,P_SONG_ID_099 ,P_SONG_ID_100
group by
vpc.SONG_ID
,vpc.STOREFRONT_ID
TYPE SONG_ID_TYPE IS TABLE OF MUSIC@MUSIC_DB%TYPE INDEX BY BINARY_INTEGER;
V_SONG_ID_ARRAY SONG_ID_TYPE ;
v_commit_counter NUMBER := 0;
BEGIN
/* open cursor you intent to bulk collect from */
OPEN C_CURRENT_MUSIC;
LOOP
/* in batches of 100, bulk collect ADAM_ID mapped TMS_IDENTIFIER into PLSQL table or records */
FETCH C_CURRENT_MUSIC BULK COLLECT INTO V_SONG_ID_ARRAY LIMIT 100;
EXIT WHEN V_SONG_ID_ARRAY.COUNT = 0;
/* to avoid NO DATA FOUND error when pass 100 parameters to OPEN cursor, if the arrary
is not fully populated to 100, pad the array with nulls to fill up to 100 cells. */
IF (V_SONG_ID_ARRAY.COUNT >=1 and V_SONG_ID_ARRAY.COUNT <> 100) THEN
FOR j IN V_SONG_ID_ARRAY.COUNT+1..100 LOOP
V_SONG_ID_ARRAY(j) := null;
END LOOP;
END IF;
/* pass a batch of 100 to cursor that get price information per SONG_ID and STOREFRONT_ID */
FOR j IN C_get_music_price_data
V_SONG_ID_ARRAY(1) ,V_SONG_ID_ARRAY(2) ,V_SONG_ID_ARRAY(3) ,V_SONG_ID_ARRAY(4) ,V_SONG_ID_ARRAY(5) ,V_SONG_ID_ARRAY(6) ,V_SONG_ID_ARRAY(7) ,V_SONG_ID_ARRAY(8) ,V_SONG_ID_ARRAY(9) ,V_SONG_ID_ARRAY(10) ,
V_SONG_ID_ARRAY(11) ,V_SONG_ID_ARRAY(12) ,V_SONG_ID_ARRAY(13) ,V_SONG_ID_ARRAY(14) ,V_SONG_ID_ARRAY(15) ,V_SONG_ID_ARRAY(16) ,V_SONG_ID_ARRAY(17) ,V_SONG_ID_ARRAY(18) ,V_SONG_ID_ARRAY(19) ,V_SONG_ID_ARRAY(20) ,
V_SONG_ID_ARRAY(21) ,V_SONG_ID_ARRAY(22) ,V_SONG_ID_ARRAY(23) ,V_SONG_ID_ARRAY(24) ,V_SONG_ID_ARRAY(25) ,V_SONG_ID_ARRAY(26) ,V_SONG_ID_ARRAY(27) ,V_SONG_ID_ARRAY(28) ,V_SONG_ID_ARRAY(29) ,V_SONG_ID_ARRAY(30) ,
V_SONG_ID_ARRAY(31) ,V_SONG_ID_ARRAY(32) ,V_SONG_ID_ARRAY(33) ,V_SONG_ID_ARRAY(34) ,V_SONG_ID_ARRAY(35) ,V_SONG_ID_ARRAY(36) ,V_SONG_ID_ARRAY(37) ,V_SONG_ID_ARRAY(38) ,V_SONG_ID_ARRAY(39) ,V_SONG_ID_ARRAY(40) ,
V_SONG_ID_ARRAY(41) ,V_SONG_ID_ARRAY(42) ,V_SONG_ID_ARRAY(43) ,V_SONG_ID_ARRAY(44) ,V_SONG_ID_ARRAY(45) ,V_SONG_ID_ARRAY(46) ,V_SONG_ID_ARRAY(47) ,V_SONG_ID_ARRAY(48) ,V_SONG_ID_ARRAY(49) ,V_SONG_ID_ARRAY(50) ,
V_SONG_ID_ARRAY(51) ,V_SONG_ID_ARRAY(52) ,V_SONG_ID_ARRAY(53) ,V_SONG_ID_ARRAY(54) ,V_SONG_ID_ARRAY(55) ,V_SONG_ID_ARRAY(56) ,V_SONG_ID_ARRAY(57) ,V_SONG_ID_ARRAY(58) ,V_SONG_ID_ARRAY(59) ,V_SONG_ID_ARRAY(60) ,
V_SONG_ID_ARRAY(61) ,V_SONG_ID_ARRAY(62) ,V_SONG_ID_ARRAY(63) ,V_SONG_ID_ARRAY(64) ,V_SONG_ID_ARRAY(65) ,V_SONG_ID_ARRAY(66) ,V_SONG_ID_ARRAY(67) ,V_SONG_ID_ARRAY(68) ,V_SONG_ID_ARRAY(69) ,V_SONG_ID_ARRAY(70) ,
V_SONG_ID_ARRAY(71) ,V_SONG_ID_ARRAY(72) ,V_SONG_ID_ARRAY(73) ,V_SONG_ID_ARRAY(74) ,V_SONG_ID_ARRAY(75) ,V_SONG_ID_ARRAY(76) ,V_SONG_ID_ARRAY(77) ,V_SONG_ID_ARRAY(78) ,V_SONG_ID_ARRAY(79) ,V_SONG_ID_ARRAY(80) ,
V_SONG_ID_ARRAY(81) ,V_SONG_ID_ARRAY(82) ,V_SONG_ID_ARRAY(83) ,V_SONG_ID_ARRAY(84) ,V_SONG_ID_ARRAY(85) ,V_SONG_ID_ARRAY(86) ,V_SONG_ID_ARRAY(87) ,V_SONG_ID_ARRAY(88) ,V_SONG_ID_ARRAY(89) ,V_SONG_ID_ARRAY(90) ,
V_SONG_ID_ARRAY(91) ,V_SONG_ID_ARRAY(92) ,V_SONG_ID_ARRAY(93) ,V_SONG_ID_ARRAY(94) ,V_SONG_ID_ARRAY(95) ,V_SONG_ID_ARRAY(96) ,V_SONG_ID_ARRAY(97) ,V_SONG_ID_ARRAY(98) ,V_SONG_ID_ARRAY(99) ,V_SONG_ID_ARRAY(100)
LOOP
/* do stuff with data from Song and Pricing Database coming from the two
separate cursors, then continue processing more rows...
END LOOP;
/* commit after each batch of 100 SONG_IDs is processed */
COMMIT;
EXIT WHEN C_CURRENT_MUSIC%NOTFOUND; -- exit when there are no more rows to fetch from cursor
END LOOP; -- bulk fetching loop
CLOSE C_CURRENT_MUSIC; -- close cursor that was used in bulk collection
/* commit rows */
COMMIT; -- commit any remaining uncommitted data.
END;I've got a problem when using passing VARRAY of numbers as parameter to remote cursor: it takes a super long time to run, sometimes doesn't finish even after an hour as passed.
Continuing with my example in original entry, I replaced the bulk collect into PLSQL table collection with a VARRAY and i bulk collect into the VARRAY, this is fast and I know it works because I can DBMS_OUTPUT.PUT_LINE cells of VARRAY so I know it is getting populated correctly. However, when I pass the VARRAY containing 100 cells populated with SONG_IDs as parameter to cursor, execution time is over an hour and when I am expecting a few seconds.
Below code example strips the problem down to it's raw details, I skip the bulk collect and just manually populate a VARRAY with 100 SONG_ID values, then try to pass to as parameter to a cursor, but the execution time of cursor is unexpectedly long, over 30 minutes, sometime longer, when I am expecting seconds.
IMPORTANT: If I take the same 100 SONG_IDs and place them directly in the cursor query's where IN clause, the SQL runs in under 5 seconds and returns result. Also, if I pass the 100 SONG_IDs as individual cells of a PLSQL table collection, then it also runs fast.
I thought that since the VARRAY is used via select subquery that is it queried locally, but the cursor is remote, and that I had a distribute problem on my hands, so I put in the DRIVING_SITE hint to attempt to force the result of query against VARRAY to go to remote server and rest of query will run there before returning result, but that didn't work either, still got slow response.
Is something wrong with my code, or I am running into a Oracle problem that may require support to resolve?
DECLARE
/* define a parameterized cursor that accepts XXX number of in SONG_IDs and
retrieves required pricing information
CURSOR C_get_music_price_data
p_array_song_ids SYS.ODCInumberList
IS
select /*+DRIVING_SITE(pd) */
count(distinct s.EVE_ID)
from PRICE_DATA@PRICING_DB pd
where pd.COUNTRY = 'USA'
and pd.START_DATE <= sysdate
and pd.END_DATE > sysdate
and pd.SONG_ID IN
select column_value from table(p_array_song_ids)
group by
pd.SONG_ID
,pd.STOREFRONT_ID
V_ARRAY_SONG_IDS SYS.ODCInumberList := SYS.ODCInumberList();
BEGIN
V_ARRAY_SONG_IDS.EXTEND(100);
V_ARRAY_SONG_IDS( 1 ) := 31135 ;
V_ARRAY_SONG_IDS( 2 ) := 31140 ;
V_ARRAY_SONG_IDS( 3 ) := 31142 ;
V_ARRAY_SONG_IDS( 4 ) := 31144 ;
V_ARRAY_SONG_IDS( 5 ) := 31146 ;
V_ARRAY_SONG_IDS( 6 ) := 31148 ;
V_ARRAY_SONG_IDS( 7 ) := 31150 ;
V_ARRAY_SONG_IDS( 8 ) := 31152 ;
V_ARRAY_SONG_IDS( 9 ) := 31154 ;
V_ARRAY_SONG_IDS( 10 ) := 31156 ;
V_ARRAY_SONG_IDS( 11 ) := 31158 ;
V_ARRAY_SONG_IDS( 12 ) := 31160 ;
V_ARRAY_SONG_IDS( 13 ) := 33598 ;
V_ARRAY_SONG_IDS( 14 ) := 33603 ;
V_ARRAY_SONG_IDS( 15 ) := 33605 ;
V_ARRAY_SONG_IDS( 16 ) := 33607 ;
V_ARRAY_SONG_IDS( 17 ) := 33609 ;
V_ARRAY_SONG_IDS( 18 ) := 33611 ;
V_ARRAY_SONG_IDS( 19 ) := 33613 ;
V_ARRAY_SONG_IDS( 20 ) := 33615 ;
V_ARRAY_SONG_IDS( 21 ) := 33617 ;
V_ARRAY_SONG_IDS( 22 ) := 33630 ;
V_ARRAY_SONG_IDS( 23 ) := 33632 ;
V_ARRAY_SONG_IDS( 24 ) := 33636 ;
V_ARRAY_SONG_IDS( 25 ) := 33638 ;
V_ARRAY_SONG_IDS( 26 ) := 33640 ;
V_ARRAY_SONG_IDS( 27 ) := 33642 ;
V_ARRAY_SONG_IDS( 28 ) := 33644 ;
V_ARRAY_SONG_IDS( 29 ) := 33646 ;
V_ARRAY_SONG_IDS( 30 ) := 33648 ;
V_ARRAY_SONG_IDS( 31 ) := 33662 ;
V_ARRAY_SONG_IDS( 32 ) := 33667 ;
V_ARRAY_SONG_IDS( 33 ) := 33669 ;
V_ARRAY_SONG_IDS( 34 ) := 33671 ;
V_ARRAY_SONG_IDS( 35 ) := 33673 ;
V_ARRAY_SONG_IDS( 36 ) := 33675 ;
V_ARRAY_SONG_IDS( 37 ) := 33677 ;
V_ARRAY_SONG_IDS( 38 ) := 33679 ;
V_ARRAY_SONG_IDS( 39 ) := 33681 ;
V_ARRAY_SONG_IDS( 40 ) := 33683 ;
V_ARRAY_SONG_IDS( 41 ) := 33685 ;
V_ARRAY_SONG_IDS( 42 ) := 33700 ;
V_ARRAY_SONG_IDS( 43 ) := 33702 ;
V_ARRAY_SONG_IDS( 44 ) := 33704 ;
V_ARRAY_SONG_IDS( 45 ) := 33706 ;
V_ARRAY_SONG_IDS( 46 ) := 33708 ;
V_ARRAY_SONG_IDS( 47 ) := 33710 ;
V_ARRAY_SONG_IDS( 48 ) := 33712 ;
V_ARRAY_SONG_IDS( 49 ) := 33723 ;
V_ARRAY_SONG_IDS( 50 ) := 33725 ;
V_ARRAY_SONG_IDS( 51 ) := 33727 ;
V_ARRAY_SONG_IDS( 52 ) := 33729 ;
V_ARRAY_SONG_IDS( 53 ) := 33731 ;
V_ARRAY_SONG_IDS( 54 ) := 33733 ;
V_ARRAY_SONG_IDS( 55 ) := 33735 ;
V_ARRAY_SONG_IDS( 56 ) := 33737 ;
V_ARRAY_SONG_IDS( 57 ) := 33749 ;
V_ARRAY_SONG_IDS( 58 ) := 33751 ;
V_ARRAY_SONG_IDS( 59 ) := 33753 ;
V_ARRAY_SONG_IDS( 60 ) := 33755 ;
V_ARRAY_SONG_IDS( 61 ) := 33757 ;
V_ARRAY_SONG_IDS( 62 ) := 33759 ;
V_ARRAY_SONG_IDS( 63 ) := 33761 ;
V_ARRAY_SONG_IDS( 64 ) := 33763 ;
V_ARRAY_SONG_IDS( 65 ) := 33775 ;
V_ARRAY_SONG_IDS( 66 ) := 33777 ;
V_ARRAY_SONG_IDS( 67 ) := 33779 ;
V_ARRAY_SONG_IDS( 68 ) := 33781 ;
V_ARRAY_SONG_IDS( 69 ) := 33783 ;
V_ARRAY_SONG_IDS( 70 ) := 33785 ;
V_ARRAY_SONG_IDS( 71 ) := 33787 ;
V_ARRAY_SONG_IDS( 72 ) := 33789 ;
V_ARRAY_SONG_IDS( 73 ) := 33791 ;
V_ARRAY_SONG_IDS( 74 ) := 33793 ;
V_ARRAY_SONG_IDS( 75 ) := 33807 ;
V_ARRAY_SONG_IDS( 76 ) := 33809 ;
V_ARRAY_SONG_IDS( 77 ) := 33811 ;
V_ARRAY_SONG_IDS( 78 ) := 33813 ;
V_ARRAY_SONG_IDS( 79 ) := 33815 ;
V_ARRAY_SONG_IDS( 80 ) := 33817 ;
V_ARRAY_SONG_IDS( 81 ) := 33819 ;
V_ARRAY_SONG_IDS( 82 ) := 33821 ;
V_ARRAY_SONG_IDS( 83 ) := 33823 ;
V_ARRAY_SONG_IDS( 84 ) := 33825 ;
V_ARRAY_SONG_IDS( 85 ) := 33839 ;
V_ARRAY_SONG_IDS( 86 ) := 33844 ;
V_ARRAY_SONG_IDS( 87 ) := 33846 ;
V_ARRAY_SONG_IDS( 88 ) := 33848 ;
V_ARRAY_SONG_IDS( 89 ) := 33850 ;
V_ARRAY_SONG_IDS( 90 ) := 33852 ;
V_ARRAY_SONG_IDS( 91 ) := 33854 ;
V_ARRAY_SONG_IDS( 92 ) := 33856 ;
V_ARRAY_SONG_IDS( 93 ) := 33858 ;
V_ARRAY_SONG_IDS( 94 ) := 33860 ;
V_ARRAY_SONG_IDS( 95 ) := 33874 ;
V_ARRAY_SONG_IDS( 96 ) := 33879 ;
V_ARRAY_SONG_IDS( 97 ) := 33881 ;
V_ARRAY_SONG_IDS( 98 ) := 33883 ;
V_ARRAY_SONG_IDS( 99 ) := 33885 ;
V_ARRAY_SONG_IDS(100 ) := 33889 ;
/* do stuff with data from Song and Pricing Database coming from the two
separate cursors, then continue processing more rows...
FOR i IN C_get_music_price_data( v_array_song_ids ) LOOP
. (this is the loop where I pass in v_array_song_ids
. populated with only 100 cells and it runs forever)
END LOOP;
END; -
hi all,
I am doing report in which there is opening stock , closing stock and all movement wise stock.
i am able to do all this for one material but when i am try for more than one material then value of last material is overwrite on other material.
I m using collect stmt to do sum for all movement.
plz help me.hi all,
plz see my code look like this :
TABLES : MSEG , MKPF , MAKT , MBEW.
DATA : BEGIN OF ITAB OCCURS 0,
LBKUM LIKE MSEG-LBKUM,
LBKUM1 LIKE MSEG-LBKUM,
MAKTX LIKE MAKT-MAKTX,
LGORT LIKE MSEG-LGORT,
BWART LIKE MSEG-BWART,
ZEILE LIKE MSEG-ZEILE,
MENGE LIKE MSEG-MENGE,
MEINS LIKE MSEG-MEINS,
MATNR LIKE MSEG-MATNR,
WERKS LIKE MSEG-WERKS,
SHKZG LIKE MSEG-SHKZG,
MBLNR LIKE MKPF-MBLNR,
BUDAT LIKE MKPF-BUDAT,
SIGN(2),
101_102 LIKE MSEG-MENGE,
END OF ITAB.
DATA : BEGIN OF ITAB_TOT OCCURS 0,
MATNR LIKE MSEG-MATNR,
LBKUM1 LIKE MSEG-LBKUM,
TOTAL1 LIKE MSEG-MENGE,
TOTAL1 TYPE P DECIMALS 3,
CLO TYPE P DECIMALS 3,
101_102 LIKE MSEG-MENGE,
END OF ITAB_TOT.
PARAMETERS : WERKS LIKE MSEG-WERKS DEFAULT 'BRHP' OBLIGATORY.
SELECT-OPTIONS : MATNR FOR MSEG-MATNR OBLIGATORY.
SELECT-OPTIONS: DAT FOR MKPF-BUDAT.
SELECT-OPTIONS: LGORT FOR MSEG-LGORT.
START-OF-SELECTION.
SELECT DISTINCT MSEG~MATNR
MSEG~LGORT
MSEG~BWART
MSEG~ZEILE
MSEG~MENGE
MSEG~MEINS
MSEG~WERKS
MSEG~LBKUM
MSEG~SHKZG
MKPF~MBLNR
MKPF~BUDAT
INTO CORRESPONDING FIELDS OF TABLE ITAB
FROM MSEG
INNER JOIN MKPF ON MSEG~MBLNR = MKPF~MBLNR
WHERE MSEG~MATNR IN MATNR
AND MSEG~LGORT IN LGORT
AND MSEG~WERKS EQ WERKS
AND mKPF~BUDAT IN DAT
AND MSEG~ZEILE = 1
order by mkpf~MBLNR.
LOOP AT ITAB.
IF ITAB-SHKZG = 'S'.
ITAB-SIGN = '+'.
MODIFY ITAB.
ELSE.
ITAB-SIGN = '-'.
MODIFY ITAB.
ENDIF.
ENDLOOP.
SORT ITAB BY MATNR.
LOOP AT ITAB.
IF ITAB-BWART = '121' OR ITAB-BWART = '122' .
SELECT MENGE INTO (ITAB-121_122) FROM MSEG WHERE MATNR =
ITAB-MATNR
AND MBLNR = ITAB-MBLNR
AND LGORT = ITAB-LGORT
AND WERKS = ITAB-WERKS.
AND ZEILE = ITAB-ZEILE.
MODIFY ITAB.
ENDSELECT.
ENDIF.
LOOP AT ITAB.
IF ITAB-SHKZG = 'H'.
ITAB-121_122 = ITAB-121_122 * -1.
MODIFY ITAB.
ELSE.
ITAB-121_122 = ITAB-121_122.
MODIFY ITAB.
ENDIF.
ENDLOOP.
ENDLOOP.
LOOP AT ITAB.
SELECT LBKUM INTO (ITAB-LBKUM) FROM MSEG WHERE MATNR = ITAB-MATNR
and
MBLNR = ITAB-MBLNR AND WERKS = ITAB-WERKS AND ZEILE = 1.
MODIFY ITAB.
ENDSELECT.
ENDLOOP.
SORT ITAB BY matnr mblnr.
LOOP AT ITAB.
IF ITAB[] IS NOT INITIAL.
DELETE ADJACENT DUPLICATES FROM ITAB COMPARING MATNR .
MOVE ITAB-lBKUM TO ITAB-LBKUM1.
MODIFY ITAB.
*APPEND ITAB_TOT1.
ENDIF.
ENDLOOP.
LOOP AT ITAB .
MOVE-CORRESPONDING ITAB TO ITAB_TOT.
COLLECT ITAB_TOT.
ENDLOOP.
loop at itab_tot.
write : / itab_tot-matnr , itab_tot-121_122 , itab-lbkum.
endloop.
i am not getting correct value of 121_122.
what should i do? -
A better way than a global temp table to reuse a distinct select?
I get the impression from other threads that global temp tables are frowned upon so I'm wondering if there is a better way to simplify what I need to do. I have some values scattered about a table with a relatively large number of records. I need to distinct them out and delete from 21 other tables where those values also occur. The values have a really low cardinality to the number of rows. Out of 500K+ rows there might be a dozen distinct values.
I thought that rather than 21 cases of:
DELETE FROM x1..21 WHERE value IN (SELECT DISTINCT value FROM Y)
It would be better for performance to populate a global temp table with the distinct first:
INSERT INTO gtt SELECT DISTINCT value FROM Y
DELETE FROM x1..21 WHERE value IN (SELECT value FROM GTT)
People asking questions about GTT's seem to get blasted so is this another case where there's a better way to do this? Should I just have the system bite the bullet on the DISTINCT 21 times? The big table truncates and reloads and needs to do so quickly so I was hoping not to have to index it and meddle with disable/rebuild index but if that's better than a temp table, I'll have to make do.
As far as I understand WITH ... USING can't be used to delete from multiple tables or can it?Almost, but not quite, as efficient as using a temporary table would be to use a PL/SQL collection and FORALL statements and/or referencing the collection in your subsequent statements). Something like
DECLARE
TYPE value_nt IS TABLE OF y.value%type;
l_values value_nt;
BEGIN
SELECT distinct value
BULK COLLECT INTO l_values
FROM y;
FORALL i IN 1 .. l_values.count
DELETE FROM x1
WHERE value = l_values(i);
FORALL i IN 1 .. l_values.count
DELETE FROM x2
WHERE value = l_values(i);
END;or
CREATE TYPE value_nt
IS TABLE OF varchar2(100); -- Guessing at the type of y.value
DECLARE
l_values value_nt;
BEGIN
SELECT distinct value
BULK COLLECT INTO l_values
FROM y;
DELETE FROM x1
WHERE value = (SELECT /*+ cardinality(v 10) */ column_value from table( l_values ) v );
DELETE FROM x2
WHERE value = (SELECT /*+ cardinality(v 10) */ column_value from table( l_values ) v );
END;Justin
Maybe you are looking for
-
Dear Experts, We have the following business scenario of export custom production. The details process of this scenario is given below for your understanding: Steps: 1. Order received from customer for finished goods 2. Raw material (input ma
-
How to install Windows 7 over corrupt Windows XP
Hello,I have a MSI U 100 wind Netbook with Windows XP. I suddenly get this Mistake: Windows could not start because the following file is missing or corrupt: \WINDOWS\SYSTEM32\CONFIG\SYSTEM I would like to install Windows 7 Home 32 bit now. Can I ju
-
Items purchased on my iPad lost when synced to MacBook Pro
I purchased music and TV shows on my iPad which downloaded fine. When I synced my iPad to my MacBook Pro they have all disappeared. I did nothing different to what I normally do when syncing and am really annoyed. I 'reported a problem' via my order
-
While use of IL01, is there a way to enforce entry of characters?
When creating a new functional location using IL01, is there a way to enforce entry of a character in each space?, to ensure there are NO blank spaces? I have a new FLoc Structure created. NNNNA-XXXXXX-XXXXXX-XXXXXX-XXXXXX The business is asking if
-
Hello, I am trying to use a page item: If the value is missing, then get a new value from a db sequence else Automated Row Fetch and display a row using the item. I can get these working but only if I have one and not the other programmed as 'page pr