Oracle JOIN в курсоре, только если найдены определенные метаданные для входного параметра

У меня есть курсор с таким соединением:

CURSOR C1 IS
SELECT *
        FROM table_1 a
             JOIN table_2 b
                                ON b.ID_1 = a.ID_1
       WHERE     TABLE_ID IS NOT NULL
             AND TABLE_ID = p_input_id; 

Я хочу изменить курсор и добавить еще 3 соединения, только если p_input_id найден в таблице метаданных. Итак, я хочу сделать что-то вроде этого:

CURSOR C1 IS
SELECT *
        FROM table_1 a
             JOIN table_2 b
                                ON b.ID_1 = a.ID_1
             CASE 
                 WHEN EXISTS (SELECT 1 
                              FROM METADATA_TABLE 
                              WHERE INPUT_ID = p_input_id 
                              AND FLAG = 'Y') 
                 THEN 
                     JOIN table_3 c
                                        ON c.ID_2 = b.ID_2
                     JOIN table_4 d
                                        ON d.ID_3 = c.ID_3
             END
       WHERE     TABLE_ID IS NOT NULL
             AND TABLE_ID = p_input_id; 

Как я могу это сделать? Я мог бы рассмотреть возможность использования LEFT JOIN вместо case/join. Есть ли какие-либо проблемы с этим?

CURSOR C1 IS
SELECT *
        FROM table_1 a
             JOIN table_2 b
                                ON b.ID_1 = a.ID_1
             LEFT JOIN table_3 c
                                ON c.ID_2 = b.ID_2
             LEFT JOIN table_4 d
                                ON d.ID_3 = c.ID_3
       WHERE     TABLE_ID IS NOT NULL
             AND TABLE_ID = p_input_id; 

Я пытаюсь не сломать текущий курсор для p_input_id, которые его используют. Будут новые p_input_id, которые должны использовать дополнительные объединения таблиц.


person user3224907    schedule 12.04.2020    source источник
comment
Вы можете использовать динамический SQL и EXECUTE IMMEDIATE. Подготовьте строку sql на основе входного значения.   -  person Lalit Kumar B    schedule 13.04.2020
comment
Я добавил еще несколько обновлений. Пожалуйста, посмотрите, выполнить немедленно - единственный путь?   -  person user3224907    schedule 13.04.2020
comment
До сих пор не ясно, каково ваше требование. Если у вас есть правильные отношения между таблицами, вам просто нужно объединить все таблицы, включая таблицу метаданных, и поместить ввод в качестве фильтра.   -  person Lalit Kumar B    schedule 13.04.2020
comment
Вы не говорите четко, чего хотите — неверный код ничего не значит. Поэтому мы не можем сказать вам, правильный ли ваш окончательный код. Почему бы или не было бы это? Что такое четкая спецификация? Используйте достаточное количество слов, предложений и ссылок на части примеров, чтобы ясно и полностью выразить то, что вы имеете в виду. Предоставляя деловые отношения (корабль) / ассоциацию или таблицу (базу или результат запроса), скажите, что строка в ней говорит о деловой ситуации с точки зрения значений ее столбца, или скажите, какие строки вы хотите с точки зрения того, что находится в таблицах. Кажется, вам нужны некоторые столбцы из некоторых строк перекрестного соединения этих таблиц — каких?   -  person philipxy    schedule 13.04.2020


Ответы (1)


Вы можете использовать LEFT JOIN для table_3 и table_4 и count в таблице metadata следующим образом:

SELECT * FROM TABLE_1 A
    JOIN TABLE_2 B ON B.ID_1 = A.ID_1
    JOIN ( SELECT COUNT(1) AS CNT
             FROM METADATA_TABLE
            WHERE INPUT_ID = P_INPUT_ID
              AND FLAG = 'Y') MT
    LEFT JOIN TABLE_3 C ON C.ID_2 = B.ID_2
                           AND MT.CNT > 0
    JOIN TABLE_4 D ON D.ID_3 = C.ID_3
                      AND MT.CNT > 0
WHERE TABLE_ID IS NOT NULL
  AND TABLE_ID = P_INPUT_ID;

COUNT используется в таблице metadata, чтобы гарантировать, что она возвращает только одну запись (замена exists).

person Popeye    schedule 13.04.2020