ORA-00907 Отсутствует правый Парантез

#sql #oracle

Вопрос:

При обработке приведенного ниже запроса я получаю ошибку «Отсутствует правая скобка» в подзапросе SELECT.

 SELECT DESCRIPTION, TOTAL_ADMISSION, EMERGENCY, NORMAL      
FROM TABLE (ORDERENTRY.PKG_S04REP00031.ADMISSION_SUMMARY
(P_START_DATE => to_date('01/08/2021', 'dd/mm/yyyy'),
P_END_DATE => to_date('01/09/2021', 'dd/mm/yyyy'),
P_ADMISSION_TYPE    => 'N',
P_ORDER_LOCATION_ID in (SELECT DESCRIPTION FROM DEFINITIOS.DEPARTMENT),
P_LOCATION_ID => 'K01'));
 

Комментарии:

1. это невозможно. Хотя в PLSQL может быть обходной путь. Имейте в виду, что функция таблицы не может получить более одного значения для p_order_location_id . Для этого вам нужно будет изменить код функции таблицы.

2. можете ли вы использовать PLSQL ?

3. @RobertoHernandez Это невозможно с таким синтаксисом; однако можно использовать эквивалентную конструкцию в SQL для вызова функции для каждой строки другой таблицы. Вам не нужно использовать PL/SQL.

4. @MTO, спасибо за ваш комментарий. Я знаю, что синтаксис невозможен. Я спрашивал ОП, может ли он использовать PLSQL, но если у вас есть решение только на SQL, это тоже неплохо.

Ответ №1:

Из Oracle 12c вы можете использовать CROSS APPLY :

 SELECT t.DESCRIPTION,
       t.TOTAL_ADMISSION,
       t.EMERGENCY,
       t.NORMAL      
FROM   DEFINITIOS.DEPARTMENT d
       CROSS APPLY TABLE(
         ORDERENTRY.PKG_S04REP00031.ADMISSION_SUMMARY(
           P_START_DATE        => DATE '2021-08-01',
           P_END_DATE          => DATE '2021-09-01',
           P_ADMISSION_TYPE    => 'N',
           P_ORDER_LOCATION_ID => d.description,
           P_LOCATION_ID       => 'K01'
         )
       ) t;
 

или CROSS JOIN LATERAL :

 SELECT t.DESCRIPTION,
       t.TOTAL_ADMISSION,
       t.EMERGENCY,
       t.NORMAL      
FROM   DEFINITIOS.DEPARTMENT d
       CROSS JOIN LATERAL (
         SELECT *
         FROM   TABLE(
           ORDERENTRY.PKG_S04REP00031.ADMISSION_SUMMARY(
             P_START_DATE        => DATE '2021-08-01',
             P_END_DATE          => DATE '2021-09-01',
             P_ADMISSION_TYPE    => 'N',
             P_ORDER_LOCATION_ID => d.description,
             P_LOCATION_ID       => 'K01'
           )
         )
       ) t;
 

бд<>скрипка <>здесь

Комментарии:

1. В качестве альтернативы используйте стандарт, соответствующий стандарту cross join lateral , вместо нестандартного cross apply

2. @a_horse_with_no_name Я добавил эту опцию; однако для ее большей типизации, поскольку для бокового соединения требуется SELECT , а не прямое использование выражения коллекции таблиц.

3. Ух ты, я и не знал, что это так ограничено.

4. @a_horse_with_no_name Мне пришлось проверить синтаксическую схему , чтобы убедиться, что нет другого способа сделать это, но LATERAL только перед a subquery (и синтаксис, похоже, не изменится в более поздних версиях ).

Ответ №2:

Вы не можете вызвать процедуру/функцию с таким параметром, как P_ORDER_LOCATION_ID в (ВЫБЕРИТЕ ОПИСАНИЕ ИЗ ОПРЕДЕЛЕНИЙ.ОТДЕЛ) предполагается, что это будет P_ORDER_LOCATION_ID =>

но все равно — вызов параметра select в процедуре/функции?