Menggabungkan 2 if memblokir dan membuat kueri tunggal

Aug 20 2020

Apakah ada kemungkinan untuk menggabungkan kedua blok if dan membuat satu blok dari bawah. Keduanya terhubung secara logis.

Jika p_update_mode adalah FUll maka saya harus menambahkan semua data tabel yang diteruskan untuk P_entity_type. Jika incremental maka saya sudah memasukkan kondisi join untuk menambahkan add yang dipilih. juga jika p_entity_type adalah null maka kita harus menambahkan data untuk tabel item dan 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;

Jawaban

2 KevinMcCabe Aug 21 2020 at 04:58

(CATATAN: kode ini belum teruji dan saya mungkin tidak menggunakan koma di sini atau tanda kurung di sana ...)

Kedua blok tersebut tampaknya hanya berbeda dalam kolom tindakan dan gabungan, sehingga Anda dapat menghilangkan 2 kaki IF dan memindahkan pemeriksaan p_update_mode ke dalam pernyataan CASE seperti ini:

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;

Kueri di blok FULL Anda mengatakan kita tidak boleh bergabung ke B dalam mode ini. Jadi klausa LEFT JOIN hanya mengembalikan baris ketika dalam mode INCREMENTAL, tetapi seharusnya tidak menghasilkan baris untuk mode FULL.

Ini harus berupa gabungan KIRI atau kami mungkin tidak mendapatkan baris apa pun dari data_view Anda yang tidak sesuai dengan entitas di B untuk mode LENGKAP. Dengan kata lain, jika ini tetap menjadi GABUNG biasa, keseluruhan kueri Anda akan mendapatkan baris nol dalam mode LENGKAP karena klausa DAN dalam gabungan.

Terakhir, filter AND di klausa WHERE di bagian bawah menjadi penting karena sekarang ada LEFT JOIN. Tanpa ini, ketika berjalan dalam mode INCREMENTAL, Anda akan mendapatkan SETIAP baris dalam data_view Anda KECUALI apakah ada baris entitas yang sesuai di B atau tidak. Meskipun Anda bergabung di entity_id, gabungan kiri akan mengembalikan baris untuk setiap baris di T bahkan tanpa baris yang cocok di B, karena untuk itulah LEFT JOIN dirancang.

Semua yang dikatakan, Anda harus memutuskan apakah layak untuk memadukan kedua blok ini. Hanya karena Anda BISA, bukan berarti Anda HARUS. Performa Anda mungkin lebih baik membiarkannya seperti yang Anda miliki - jalankan beberapa tes. Hanya Anda yang mengetahui volume data dan frekuensi pemrosesannya. Anda juga perlu mempertimbangkan pemeliharaan kode Anda, karena pria / wanita berikutnya harus mencari tahu apa yang terjadi di sini.