Combinando 2 if block e creando una singola query

Aug 20 2020

Esiste la possibilità di unire entrambi i blocchi if e creare un singolo blocco dal basso. Entrambi sono collegati logicamente.

Se è p_update_mode è FUll, allora devo aggiungere tutti i dati della tabella passati per P_entity_type. se è incrementale, ho messo la condizione di join per aggiungere l'aggiunta selezionata. anche se p_entity_type è nullo, dobbiamo aggiungere i dati sia per le tabelle degli elementi che per quelle dell'organizzazione.

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;

Risposte

2 KevinMcCabe Aug 21 2020 at 04:58

(NOTA: questo codice non è stato testato e potrei essere fuori da una virgola qui o da una parentesi lì ...)

Questi due blocchi sembrano differire solo nella colonna delle azioni e in un join, quindi potresti eliminare le 2 gambe IF e spostare il controllo di p_update_mode in un'istruzione CASE come questa:

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;

La query nel blocco FULL dice che non dovremmo unirci a B in questa modalità. Quindi la clausola LEFT JOIN riporta indietro le righe solo in modalità INCREMENTAL, ma non dovrebbe produrre righe per la modalità FULL.

Deve essere un join LEFT o potremmo non ottenere alcuna riga dal tuo data_view che non corrisponde alle entità in B per la modalità FULL. In altre parole, se rimanesse un JOIN regolare, la query complessiva otterrebbe zero righe in modalità FULL a causa della clausola AND nel join.

Infine, il filtro AND nella clausola WHERE in basso diventa necessario ora che c'è un LEFT JOIN. Senza questo, quando si esegue in modalità INCREMENTALE, si otterrebbe OGNI riga nella data_view INDIPENDENTEMENTE dalla presenza o meno di una riga di entità corrispondente in B. Anche se ti stai unendo su entity_id, il join sinistro riporterà una riga per ogni riga in T anche senza una riga corrispondente in B, perché questo è ciò per cui i LEFT JOIN sono stati progettati.

Detto questo, dovrai decidere se vale la pena fondere questi due blocchi. Solo perché PUOI, non significa che DOVREI. Le tue prestazioni potrebbero essere migliori lasciandole come le hai fatte: esegui alcuni test. Solo tu conosci il volume dei dati e la frequenza di elaborazione. Devi anche considerare la manutenzione del tuo codice, poiché il prossimo ragazzo / ragazza dovrà capire cosa sta succedendo qui.