2 ifブロックを組み合わせて、単一のクエリを作成する

Aug 20 2020

ifブロックと下から1つのブロックの両方をマージする可能性はありますか?両方とも論理的に接続されています。

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;

回答

2 KevinMcCabe Aug 21 2020 at 04:58

(注:このコードはテストされておらず、ここではコンマまたは括弧で囲まれていない可能性があります...)

これらの2つのブロックは、アクション列と結合のみが異なるように見えるため、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モードの場合は行を生成しないはずです。

これは左結合である必要があります。そうしないと、フルモードのBのエンティティに対応しない行がdata_viewから取得されない可能性があります。つまり、これが通常のJOINのままである場合、結合のAND句が原因で、クエリ全体でFULLモードで行がゼロになります。

最後に、LEFT JOINがあるため、下部のWHERE句のANDフィルターが必要になります。これがないと、INCREMENTALモードで実行すると、Bに対応するエンティティ行があるかどうかに関係なく、data_viewにすべての行が表示されます。entity_idで結合している場合でも、左結合では、Bに一致する行がなくても、Tの各行の行が戻されます。これは、LEFTJOINが行うように設計されているためです。

そうは言っても、これら2つのブロックをブレンドする価値があるかどうかを判断する必要があります。できるからといって、すべきだという意味ではありません。パフォーマンスは、そのままにしておく方が良い場合があります。いくつかのテストを実行してください。データの量と処理の頻度を知っているのはあなただけです。次の男/ギャルはここで何が起こっているのかを理解する必要があるため、コードの保守も考慮する必要があります。