การรวม 2 if block และสร้างแบบสอบถามเดียว

Aug 20 2020

มีความเป็นไปได้หรือไม่ที่จะรวมทั้ง if block และสร้าง single block จากด้านล่าง ทั้งสองเชื่อมต่อกันอย่างมีเหตุผล

ถ้าเป็น p_update_mode คือ FUll ฉันต้องเพิ่มข้อมูลทั้งหมดของตารางที่ส่งผ่านสำหรับ P_entity_type หากเป็นแบบเพิ่มหน่วยฉันได้ใส่เงื่อนไขการเข้าร่วมเพื่อเพิ่มการเพิ่มที่เลือก และถ้า p_entity_type เป็นโมฆะเราจะต้องเพิ่มข้อมูลสำหรับทั้งรายการและตารางองค์กร

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

(หมายเหตุ: รหัสนี้ยังไม่ผ่านการทดสอบและฉันอาจปิดเครื่องหมายจุลภาคที่นี่หรืออยู่ในวงเล็บ ... )

ทั้งสองบล็อกดูเหมือนจะแตกต่างกันในคอลัมน์การดำเนินการและการรวมดังนั้นคุณสามารถกำจัดขา IF 2 ขาและย้ายการตรวจสอบ 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;

ข้อความค้นหาในบล็อกเต็มของคุณบอกว่าเราไม่ควรเข้าร่วมกับ B ในโหมดนี้ ดังนั้นประโยค LEFT JOIN จะนำแถวย้อนกลับเมื่ออยู่ในโหมด INCREMENTAL เท่านั้น แต่ไม่ควรสร้างแถวสำหรับโหมดเต็ม

สิ่งนี้จำเป็นต้องเป็นการรวม LEFT มิฉะนั้นเราอาจไม่ได้รับแถวใด ๆ จาก data_view ของคุณที่ไม่ตรงกับเอนทิตีใน B สำหรับโหมดเต็ม กล่าวอีกนัยหนึ่งคือหากยังคงเป็นการเข้าร่วมปกติข้อความค้นหาโดยรวมของคุณจะได้รับแถวเป็นศูนย์ในโหมดเต็มเนื่องจากส่วนคำสั่ง AND ในการรวม

สุดท้ายตัวกรอง AND ในส่วนคำสั่ง WHERE ที่ด้านล่างกลายเป็นสิ่งที่จำเป็นในตอนนี้ที่มีการเข้าร่วมทางซ้าย หากไม่มีสิ่งนี้เมื่อทำงานในโหมด INCREMENTAL คุณจะได้ทุกแถวใน data_view ของคุณ REGARDLESS ว่ามีแถวเอนทิตีที่เกี่ยวข้องใน B หรือไม่ แม้ว่าคุณจะเข้าร่วมใน entity_id การรวมด้านซ้ายจะนำแถวกลับมาสำหรับแต่ละแถวใน T แม้ว่าจะไม่มีแถวที่ตรงกันใน B ก็ตามเพราะนั่นคือสิ่งที่ LEFT JOIN ได้รับการออกแบบมา

ทั้งหมดที่กล่าวมาคุณจะต้องตัดสินใจว่าจะคุ้มค่ากับการผสมสองบล็อกนี้หรือไม่ เพียงเพราะคุณทำได้ไม่ได้หมายความว่าคุณควร ประสิทธิภาพของคุณอาจดีกว่าโดยปล่อยให้เป็นแบบที่คุณมี - ทำการทดสอบบางอย่าง มีเพียงคุณเท่านั้นที่รู้ปริมาณข้อมูลและความถี่ในการประมวลผล คุณต้องพิจารณาการบำรุงรักษารหัสของคุณด้วยเพราะผู้ชาย / สาวคนต่อไปจะต้องคิดออกว่าเกิดอะไรขึ้นที่นี่