riga di codice ripetitiva della procedura plsql. cercando di fare in modo migliore

Aug 21 2020

Ho uno scenario. Se l'utente passa il parametro, Entity_typeè necessario inserire i dati solo per quello entity( table). Se non passa alcun parametro, è necessario inserire i dati per tutte le tabelle richieste in una tabella.

quindi abbiamo una tabella DYNAMICENTITYGTTche prenderà i dati dalla Itemtabella se viene passata, orgtabella se viene passato. Ma prenderà i dati da entrambe le tabelle se il Entity_typeparametro è nullo in proc ..

Inoltre memorizzerà un'altra colonna a seconda del tipo di UPDATE_MODEmezzi aggiunti o eliminati. La tabella di destinazione è la stessa. tabella di origine e il nome della colonna sono diversi ma il tipo è lo stesso.

Ho scritto sotto la procedura per lo stesso.

Sto solo chiedendo che ci sia comunque per migliorare questo codice. Voglio dire, può essere scritto in un modo più intelligente? Perché sto ripetendo più righe. Ho fornito un esempio di 2 entità ma ce ne sono 7, quindi il codice sarebbe enorme.

CREATE OR REPLACE procedure UPDATE_DYNAMIC_ENTITY(ENTITY_TYPE varchar2 default null,UPDATE_MODE varchar2)
Is
x number;
BEGIN
IF UPPER(entity_type)='ITEM' then
    if upper(UPDATE_MODE)='DELETE' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'delete' from ITEMDE;
    ELSIF lower(UPDATE_MODE)='add' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'add' from ITEMDE;
    END IF;
ELSIF UPPER(entity_type)='ORG' then
    if upper(UPDATE_MODE)='DELETE' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'delete' from ORGDE;
    ELSIF lower(UPDATE_MODE)='add' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'add' from ORGDE;
    END IF;
ELSE
   if upper(UPDATE_MODE)='DELETE' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'delete' from ITEMDE;
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'delete' from ORGDE;
    ELSIF lower(UPDATE_MODE)='add' then
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,Item_id,item_name,item_desc,'add' from ITEMDE;
      INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select Entity_type,ORG_id,org_name,org_desc,'add' from ORGDE;
   END IF;
   
END IF;
END UPDATE_DYNAMIC_ENTITY;

Risposte

1 KayaNatsumi Aug 20 2020 at 22:10

Fondamentalmente vedo due inserti con due variabili che ne determinano il contenuto. Stai inserendo dall'istruzione select, quindi puoi manipolare queste selezioni per non restituire valori quando le condizioni non sono come previsto.

Per il parametro p_update_modeè facile, se contiene il valore "cancella" inserisci "cancella", se contiene il valore "aggiungi" inserisci "aggiungi".

Per il parametro p_entity_typeinseriamo da entrambe le selezioni quando il suo valore è "NULL", solo da itemdetabella se il valore è "ITEM" e solo da orgdetabella se il valore è "ORG".

Ora, nel caso in cui ci sia qualche valore non valido in p_entity_typenessuna delle selezioni, produrrà dati poiché riconosciamo solo "NULL", "ITEM" e "ORG". Ma per parametro p_update_modemodifichiamo direttamente il valore e lo usiamo in insert, quindi sarebbe meglio fare qualche controllo se il valore di input è valido per noi.

CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
                                                  p_update_mode VARCHAR2) IS
BEGIN
  IF lower(p_update_mode) NOT IN ('add', 'delete')
  THEN
    RAISE VALUE_ERROR; -- maybe use raise_application_error for more details about problem
  END IF;
  --
  INSERT INTO dynamicentitygtt
    (entity_type, entity_id, entity_code, synonyms, action)
    SELECT upper(NVL(p_entity_type, 'ITEM')), item_id, item_name, item_desc, lower(p_update_mode)
      FROM itemde
     WHERE upper(p_entity_type) = 'ITEM'
        OR p_entity_type IS NULL;
  --
  INSERT INTO dynamicentitygtt
    (entity_type, entity_id, entity_code, synonyms, action)
    SELECT upper(NVL(p_entity_type, 'ORG')), org_id, org_name, org_desc, lower(p_update_mode)
      FROM orgde
     WHERE upper(p_entity_type) = 'ORG'
        OR p_entity_type IS NULL;
END update_dynamic_entity;

Mentre scrivi hai 7 entità, quindi questo approccio porterebbe ad avere 7 inserti, poiché credo (e fammi sapere se sbaglio) ogni entità ha il proprio set di dati in tabelle diverse.

C'è anche la possibilità di unire tutte queste tabelle e trasformarle in un singolo inserto come nell'esempio di seguito, e ogni nuova entità significherebbe solo aggiungere una nuova selezione in una WITHparte dell'istruzione. Ma non sono sicuro delle prestazioni in questo caso. Ciò dipenderà da quanto sono pieni i tuoi tavoli.

CREATE OR REPLACE PROCEDURE update_dynamic_entity(p_entity_type VARCHAR2 DEFAULT NULL,
                                                  p_update_mode VARCHAR2) IS
BEGIN
  IF lower(p_update_mode) NOT IN ('add', 'delete')
  THEN
    RAISE VALUE_ERROR; -- maybe use raise_application_error for more details about problem
  END IF;
  --
  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
        FROM itemde
      UNION ALL
      -- ORG table
      SELECT 'ORG' entity_type, -- This separates inserted values
              org_id,
              org_name,
              org_desc
        FROM orgde
      -- NEXT entity table
      )
    SELECT upper(entity_type), data_id, data_name, data_desc, lower(p_update_mode)
      FROM data_view
     WHERE upper(p_entity_type) = entity_type
        OR p_entity_type IS NULL;
END update_dynamic_entity;

E anche se questo diventa complicato per te, puoi creare un punto in VIEWcui fai le se UNIONrimuoverlo WITHda PROCEDUREe con nuove entità aggiungendo selezioni al VIEWposto di PROCEDURE.