Oracle 11g и функция сбора - PullRequest
       1

Oracle 11g и функция сбора

2 голосов
/ 24 февраля 2012

Я использую БД ORACLE 11g через инструмент разработки SQL.
Невозможно использовать функцию Collect с предложением Distinct. Когда используется в моей процедуре, он не распознает!

Мой запрос для справки:

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, '')

Здесь varchar2_ntt:

create or replace TYPE varchar2_ntt AS TABLE OF VARCHAR2(4000);

Возвращенная ошибка:

Error(49,6): PL/SQL: ORA-30482: DISTINCT option not allowed for this function

Ответы [ 2 ]

1 голос
/ 28 февраля 2012

Это старая проблема в Oracle, когда парсеры движка SQL и PL / SQL различаются, и в этом случае PL / SQL не позволит использовать distinct в агрегированной функции. См. this Ответ AskTom от 2003 года относительно этого.

Его совет - использовать динамически открываемый реф-курсор. Другими решениями было бы заключить ваш запрос во внешний запрос (такой как ответ Гленна) или, по моему предпочтению, превратить его в представление и вместо этого выбрать из него. Использование динамического SQL также работает в этой ситуации.

0 голосов
/ 28 февраля 2012

Как насчет упаковки в подзапрос?

    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

Внутренняя группа by выполняет "отдельную" операцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...