riga di codice ripetitiva della procedura plsql. cercando di fare in modo migliore
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 DYNAMICENTITYGTT
che prenderà i dati dalla Item
tabella se viene passata, org
tabella se viene passato. Ma prenderà i dati da entrambe le tabelle se il Entity_type
parametro è nullo in proc ..
Inoltre memorizzerà un'altra colonna a seconda del tipo di UPDATE_MODE
mezzi 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
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_type
inseriamo da entrambe le selezioni quando il suo valore è "NULL", solo da itemde
tabella se il valore è "ITEM" e solo da orgde
tabella se il valore è "ORG".
Ora, nel caso in cui ci sia qualche valore non valido in p_entity_type
nessuna delle selezioni, produrrà dati poiché riconosciamo solo "NULL", "ITEM" e "ORG". Ma per parametro p_update_mode
modifichiamo 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 WITH
parte 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 VIEW
cui fai le se UNION
rimuoverlo WITH
da PROCEDURE
e con nuove entità aggiungendo selezioni al VIEW
posto di PROCEDURE
.