2 if 블록 결합 및 단일 쿼리 생성

Aug 20 2020

if 블록을 병합하고 아래에서 단일 블록을 만들 가능성이 있습니까? 둘 다 논리적으로 연결되어 있습니다.

p_update_mode가 FUll이면 P_entity_type에 전달 된 테이블의 모든 데이터를 추가해야합니다. 증분이면 선택한 추가를 추가하는 조인 조건을 설정했습니다. 또한 p_entity_type이 null이면 항목 및 조직 테이블 모두에 대한 데이터를 추가해야합니다.

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 개의 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 조인이어야합니다. 그렇지 않으면 FULL 모드에 대해 B의 엔터티에 해당하지 않는 data_view에서 행을 가져 오지 못할 수 있습니다. 즉, 이것이 일반 JOIN으로 남아 있으면 전체 쿼리는 조인의 AND 절로 인해 FULL 모드에서 0 행을 얻습니다.

마지막으로 LEFT JOIN이 있으므로 하단 WHERE 절의 AND 필터가 필요합니다. 이것이 없으면 INCREMENTAL 모드로 실행할 때 B에 해당 엔티티 행이 있는지 여부에 관계없이 data_view의 모든 행을 얻을 수 있습니다. entity_id에 조인하더라도 왼쪽 조인은 B에 일치하는 행이 없어도 T의 각 행에 대해 행을 다시 가져올 것입니다. 이것이 LEFT JOIN이 수행하도록 설계된 것이기 때문입니다.

즉,이 두 블록을 혼합 할 가치가 있는지 결정해야합니다. 할 수 있다고해서 반드시해야한다는 의미는 아닙니다. 당신의 성능은 당신이 가지고있는 그대로 두는 것이 더 나을 수 있습니다. 데이터의 양과 처리 빈도를 아는 사람은 당신뿐입니다. 다음 사람 / 걸이 여기서 무슨 일이 벌어지고 있는지 파악해야하기 때문에 코드 유지 관리도 고려해야합니다.