仅当为输入参数找到某个元数据时,才在游标中加入 Oracle

Posted

技术标签:

【中文标题】仅当为输入参数找到某个元数据时,才在游标中加入 Oracle【英文标题】:Oracle JOIN in cursor only if a certain metadata is found for input parameter 【发布时间】:2020-04-12 22:36:24 【问题描述】:

我有一个像这样连接的光标:

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; 

只有在元数据表中找到 p_input_id 时,我才想修改游标并再添加 3 个连接。所以我想做这样的事情:

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 需要使用额外的表连接。

【问题讨论】:

您可以使用动态 SQL 和 EXECUTE IMMEDIATE。根据输入值准备sql字符串。 我添加了一些更新。请看,立即执行是唯一的途径吗? 目前还不清楚您的要求是什么。如果表之间有适当的关系,那么您只需连接所有表,包括元数据表,并将输入作为过滤器。 你没有说清楚你想要什么——无效的代码没有任何意义。所以我们不能告诉你你的最终代码是否正确。为什么会或不会呢?什么是明确的规范?使用足够多的单词、句子和对部分示例的引用来清楚完整地表达你的意思。在给出业务关系(船舶)/关联或表(基础或查询结果)时,说明其中的一行根据其列值说明业务情况,或者根据表中的内容说明您想要哪些行。您似乎想要这些表的交叉连接的某些行中的某些列 - 哪个? 【参考方案1】:

您可以在metadata 表中将LEFT JOIN 用于table_3table_4count,如下所示:

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;

metadata 表中使用COUNT,以确保它只返回一条记录。(exists 的替换)

【讨论】:

以上是关于仅当为输入参数找到某个元数据时,才在游标中加入 Oracle的主要内容,如果未能解决你的问题,请参考以下文章

仅当使用 LayersControl 的缩放级别> 8 时,才在 Shiny 的传单地图中显示图层?

Oracle存储过程,游标使用

仅当它不存在时才在 SQLite 中创建表

仅当行已更改时,MySQL 才在更新后触发

仅当特定密钥对值与可迭代匹配时,才在 JSON 对象中获取多个 JSON 密钥对值

仅当所有文本字段都已填写时才在 Swift 中启用按钮