结合2 if阻止并创建单个查询

问题描述

是否有可能合并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,action)
    WITH data_view AS
     ( 
      SELECT 'ITEM' entity_type,'add' action
        FROM itemde
      UNION ALL
      -- ORG table
      SELECT 'ORG' entity_type,'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;

解决方法

(注意:此代码未经测试,我在这里可能不是逗号或在括号中...)

这两个块似乎仅在操作列和连接上有所不同,因此您可以消除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处于FULL模式的实体不对应的行。换句话说,如果这仍然是常规的JOIN,则由于连接中的AND子句,在FULL模式下您的整体查询将获得零行。

最后,由于有一个LEFT JOIN,因此底部WHERE子句中的AND过滤器变得必要。否则,在INCREMENTAL模式下运行时,您将在data_view中获得每行,无论B中是否存在对应的实体行。即使您在entity_id上进行联接,即使在B中没有匹配的行的情况下,左联接也将为T中的每一行带回一行,因为这是LEFT JOIN设计的目的。

所有这些,您将不得不决定是否值得将这两个区块融合在一起。仅仅因为您可以,并不意味着您应该。按照您的方式进行操作可能会更好—运行一些测试。只有您知道数据量和处理频率。您还需要考虑代码的维护,因为下一个家伙/加仑将不得不弄清楚这里发生了什么。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...