【问题标题】:Combining 2 if block and creating single query结合 2 if 块并创建单个查询
【发布时间】:2020-12-10 07:10:12
【问题描述】:

是否有可能合并 if 块并从下面创建单个块。两者在逻辑上是相连的。

如果它是 p_update_mode 是 FUll 那么我必须添加为 P_entity_type 传递的表的所有数据。如果它是增量的,那么我已经将连接条件添加到添加选定的添加。此外,如果 p_entity_type 为 null,那么我们必须为 item 和 org 表添加数据。

CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
                                                  p_update_mode VARCHAR2) IS
BEGIN
  IF lower(p_update_mode) = 'incremental'
  THEN
  INSERT INTO dynamicentitygtt
    (entity_type, entity_id, entity_code, synonyms, action)
    WITH data_view AS
     ( -- ITEM table
      SELECT 'ITEM' entity_type, -- This separates inserted values
              item_id data_id,
              item_name data_name,
              item_desc data_desc,
              creation_date
        FROM itemde
      UNION ALL
      -- ORG table
      SELECT 'ORG' entity_type, -- This separates inserted values
              org_id,
              org_name,
              org_desc,
              creation_date
        FROM orgde
      -- NEXT entity table
      )
    SELECT upper(t.entity_type),
           t.data_id,
           t.data_name,
           t.data_desc,
           CASE
             WHEN t.creation_date > b.max_last_update_date THEN
               'update'
             WHEN t.creation_date < b.max_last_update_date THEN
               'add'
           END
      FROM data_view t
      JOIN batch_run_details b
        ON b.entity_type = t.entity_type
     WHERE upper(p_entity_type) = t.entity_type
        OR p_entity_type IS NULL;
  
 END IF;
 
 IF UPPER(UPDATE_MODE)='FULL' then
   
    INSERT INTO dynamicentitygtt
    (entity_type, entity_id, entity_code, synonyms, action)
    WITH data_view AS
     ( 
      SELECT 'ITEM' entity_type, -- This separates inserted values
              item_id data_id,
              item_name data_name,
              item_desc data_desc,
              'add' action
        FROM itemde
      UNION ALL
      -- ORG table
      SELECT 'ORG' entity_type, -- This separates inserted values
              org_id,
              org_name,
              org_desc,
              'add' action
        FROM orgde
      )
    SELECT upper(entity_type), data_id, data_name, data_desc,action
      FROM data_view
     WHERE upper(p_entity_type) = entity_type
        OR p_entity_type IS NULL;
    END IF;
        
END update_dynamic_entity;

【问题讨论】:

    标签: sql database oracle plsql


    【解决方案1】:

    (注意:此代码未经测试,我可能在此处使用逗号或括号...)

    这两个块似乎只在操作列和连接上有所不同,因此您可以消除 2 个 IF 分支并将 p_update_mode 的检查移到这样的 CASE 语句中:

    CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
                                                      p_update_mode VARCHAR2) IS
    BEGIN
      INSERT INTO dynamicentitygtt
        (entity_type, entity_id, entity_code, synonyms, action)
        WITH data_view AS
         ( -- ITEM table
          SELECT 'ITEM' entity_type, -- This separates inserted values
                  item_id data_id,
                  item_name data_name,
                  item_desc data_desc,
                  creation_date
            FROM itemde
          UNION ALL
          -- ORG table
          SELECT 'ORG' entity_type, -- This separates inserted values
                  org_id,
                  org_name,
                  org_desc,
                  creation_date
            FROM orgde
          -- NEXT entity table
          )
        SELECT upper(t.entity_type),
               t.data_id,
               t.data_name,
               t.data_desc,
               CASE lower(p_update_mode)
                 WHEN 'incremental' THEN
                   CASE
                     WHEN t.creation_date > b.max_last_update_date THEN
                       'update'
                     WHEN t.creation_date < b.max_last_update_date THEN
                       'add'
                   END
                 WHEN 'full' THEN
                  'add' 
               END action
          FROM data_view t
               LEFT JOIN batch_run_details b
                      ON b.entity_type = t.entity_type
                     AND lower(p_update_mode )='incremental'
         WHERE (upper(p_entity_type) = t.entity_type OR p_entity_type IS NULL)
           AND (lower(p_update_mode) = 'full'
                OR (lower(p_update_mode) = 'incremental' AND b.entity_type IS NOT NULL)
               );
            
    END update_dynamic_entity;
    

    您的 FULL 块中的查询表明我们不应该在这种模式下加入 B。所以 LEFT JOIN 子句只在 INCREMENTAL 模式下带回行,但在 FULL 模式下不应该产生行。

    这需要是 LEFT 联接,否则我们可能无法从您的 data_view 中获取任何与 B 中的实体不对应的完整模式行。换句话说,如果这仍然是一个常规的 JOIN,由于连接中的 AND 子句,您的整个查询将在 FULL 模式下获得零行。

    最后,由于存在 LEFT JOIN,因此底部 WHERE 子句中的 AND 过滤器变得必要。如果没有这个,当在 INCREMENTAL 模式下运行时,无论 B 中是否存在相应的实体行,您都会在 data_view 中获得每一行。即使您在 entity_id 上加入,即使 B 中没有匹配的行,左连接也会为 T 中的每一行带回一行,因为这就是 LEFT JOIN 的设计目的。

    说了这么多,你将不得不决定是否值得混合这两个块。仅仅因为你可以,并不意味着你应该。你的表现可能会更好,让它保持原来的样子——运行一些测试。只有您知道数据量和处理频率。您还需要考虑代码的维护,因为下一个人/女孩必须弄清楚这里发生了什么。

    【讨论】:

    • 只是给OP的一个注释,在他之前的一些问题中提到过。有 t.creation_date &gt; b.max_last_update_datet.creation_date &lt; b.max_last_update_date 的情况,但也应处理这些日期相等的情况,以避免生成可能不需要的 action 列中的 NULL 值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多