Reputation: 29
I'm using ORACLE 11g DB, through a SQL Dev tool.
Unable to use the Collect function with a 'Distinct' clause. When used in my procedure, it's not recognising!
My Query for reference:
SELECT nvl(spicd.company_code, '') companycode
, nvl(scc.company_description, '') companydesc
, nvl(spicd.plant_code, '') plantcode
, CAST(COLLECT(DISTINCT svh.haulier_code) AS varchar2_ntt) hauliercode
, CAST(COLLECT(DISTINCT sh.hauier_name) AS varchar2_ntt) hauliername
FROM saistb_company_code scc
, saistb_pve_indv_contact_det spicd
LEFT OUTER JOIN saistb_vendor_haulier svh
ON svh.company_code = spicd.company_code
AND svh.plant_code = spicd.plant_code
AND svh.vendor_code = spicd.vendor_code
LEFT OUTER JOIN saistb_haulier sh
ON sh.haulier_code = svh.haulier_code
WHERE scc.company_code = spicd.company_code
AND spicd.company_code LIKE <<companycode>>
AND spicd.plant_code LIKE <<plantcode>>
GROUP BY nvl(spicd.company_code, '')
, nvl(scc.company_description, '')
, nvl(spicd.plant_code, '')
Here varchar2_ntt
is:
create or replace TYPE varchar2_ntt AS TABLE OF VARCHAR2(4000);
The error returned is:
Error(49,6): PL/SQL: ORA-30482: DISTINCT option not allowed for this function
Upvotes: 2
Views: 4310
Reputation: 7803
This is an old problem in Oracle where the SQL and PL/SQL engine parsers differ and, in this case, PL/SQL won't let you use distinct
in an aggregated function. See this AskTom response from 2003 regarding this.
His advice is to use a dynamically opened ref cursor. Other solutions would be to wrap your query with an outer query (like Glenn's answer) or, my preference, turn it into a view and select from that instead. Using dynamic SQL also works in this situation.
Upvotes: 1
Reputation: 9170
How about wrapping it in a subquery?
SELECT companyCode, companyDesc, plantCode,
cast(COLLECT(haulierCode) as varchar2_ntt) haulierCode,
cast(COLLECT(haulierName) as varchar2_ntt) haulierName
FROM (
SELECT
nvl(spicd.COMPANY_CODE,'') companyCode,
nvl(scc.COMPANY_DESCRIPTION,'') companyDesc,
nvl(spicd.PLANT_CODE,'') plantCode,
nvl(sh.HAULIER_CODE, 'UNKNOWN HAULIER CODE') haulierCode,
nvl(sh.haulier_name, 'UNKNOWN HAULIER NAME') haulierName
from
SAISTB_COMPANY_CODE scc,
SAISTB_PVE_INDV_CONTACT_DET spicd
left outer join SAISTB_VENDOR_HAULIER svh on
svh.COMPANY_CODE = spicd.COMPANY_CODE and
svh.PLANT_CODE = spicd.PLANT_CODE and
svh.VENDOR_CODE = spicd.VENDOR_CODE
left outer join SAISTB_HAULIER sh on
sh.HAULIER_CODE = svh.HAULIER_CODE
where
scc.COMPANY_CODE = spicd.COMPANY_CODE
and spicd.COMPANY_CODE like <<CompanyCode>>
and spicd.PLANT_CODE like <<PlantCode>>
group by
nvl(spicd.COMPANY_CODE,''),
nvl(scc.COMPANY_DESCRIPTION,''),
nvl(spicd.PLANT_CODE,''),
nvl(sh.HAULIER_CODE, 'UNKNOWN HAULIER CODE') haulierCode,
nvl(sh.haulier_name, 'UNKNOWN HAULIER NAME') haulierName
)
GROUP BY companyCode, companyDesc, plantCode
The inner group by performs the "distinct" operation.
Upvotes: 0