Ottimizzazione del codice in PL / SQL. Rendendolo corretto. Il codice è in esecuzione ma non corretto
Ho 3 set di tavoli. Tabella di origine
ORGDE(ORG_ID,ORG_NAME,ORG_DESC,CREATION_DATE,LAST_UPDATE_DATE)
ITEMDE(ITEM_ID,ITEM_NAME,ITEM_DESC,CREATION_DATE,LAST_UPDATE_DATE)
Tabella di destinazione
DYNAMICENTITYGTT(ENTITY_TYPE,ENTITY_ID,ENTITY_CODE,SYNONYMS,ACTION)
Tabella delle condizioni
BATCH_RUN_DETAILS(ENTITY_TYPE,LAST_RUN_DATE,MAX_LAST_UPDATE_DATE)
Dobbiamo inserire i dati in DYNAMICENTITYGTT da ORGDE e ITEMDE. Action in DYNAMICENTITYGTT will be 'update' where CREATION_DATE>max_last_update_dateAction in DYNAMICENTITYGTT will be 'add' where CREATION_DATE<max_last_update_datese p_entity_type è presente, inserirà i dati per quell'entità, altrimenti inserirà per entrambe le tabelle.
Ho scritto sotto il codice. voglio migliorarlo e renderlo migliore.
CREATE OR REPLACE procedure UPDATE_DYNAMIC_ENTITY(P_ENTITY_TYPE varchar2 default null,P_UPDATE_MODE varchar2)
IS
BEGIN
IF UPPER(P_UPDATE_MODE)='INCREMENTAL'
THEN
IF UPPER(p_entity_type)='ORG' then
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select P_Entity_type,ORG_id,org_name,org_desc,'add' from ORGDE where creation_date>(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select P_Entity_type,ORG_id,org_name,org_desc,'update' from ORGDE where creation_date<(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
ELSIF UPPER(p_entity_type)='ITEM' then
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select P_Entity_type,item_id,item_name,item_desc,'add' from ITEMDE where creation_date>(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select P_Entity_type,item_id,item_name,item_desc,'update' from ITEMDE where creation_date<(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
ELSIF P_ENTITY_TYPE=NULL THEN
--Reading from org
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select p_Entity_type,ORG_id,org_name,org_desc,'add' from ORGDE where creation_date>(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select p_Entity_type,ORG_id,org_name,org_desc,'update' from ORGDE where creation_date<(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
--reading from item
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select p_Entity_type,item_id,item_name,item_desc,'add' from ITEMDE where creation_date>(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
INSERT INTO DYNAMICENTITYGTT(Entity_type,Entity_id,Entity_code,Synonyms,Action) select p_Entity_type,item_id,item_name,item_desc,'update' from ITEMDE where creation_date<(select max_last_update_date from BATCH_RUN_DETAILS where ENTITY_TYPE=P_ENTITY_TYPE);
END IF;
END IF;
END UPDATE_DYNAMIC_ENTITY;
Puoi suggerire miglioramenti al codice.
Risposte
Sarebbe simile alla risposta precedente alla riga di codice ripetitiva della procedura plsql. cercando di fare in modo migliore .
Quello che facciamo ora è aggiungere JOINalla tabella che contiene batch_run_detailse case che determinerà per ogni riga quale azione deve inserire in base a creation_datee max_last_update_date.
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
RETURN; -- Do nothing if incorrect mode
END IF;
--
INSERT INTO dynamicentitygtt
(entity_type, entity_id, entity_code, synonyms, action)
SELECT upper(NVL(p_entity_type, 'ITEM')),
t.item_id,
t.item_name,
t.item_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 itemde t
JOIN batch_run_details b
ON b.entity_type = 'ITEM'
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')),
t.org_id,
t.org_name,
t.org_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 orgde t
JOIN batch_run_details b
ON b.entity_type = 'ORG'
WHERE upper(p_entity_type) = 'ORG'
OR p_entity_type IS NULL;
END update_dynamic_entity;
E solo per il completamento dal post precedente, anche la versione a inserto singolo:
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
RETURN;
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,
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 update_dynamic_entity;
La prima cosa che vorrei fare per migliorarlo è formattarlo in modo che sia leggibile. Mi ci è voluto meno tempo per formattarlo che per scrivere questa frase:
CREATE OR replace PROCEDURE Update_dynamic_entity(
p_entity_type VARCHAR2 DEFAULT NULL,
p_update_mode VARCHAR2)
IS
BEGIN
IF Upper(p_update_mode) = 'INCREMENTAL' THEN
IF Upper(p_entity_type) = 'ORG' THEN
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT p_entity_type,
org_id,
org_name,
org_desc,
'add'
FROM orgde
WHERE creation_date > (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT p_entity_type,
org_id,
org_name,
org_desc,
'update'
FROM orgde
WHERE creation_date < (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
ELSIF Upper(p_entity_type) = 'ITEM' THEN
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT p_entity_type,
item_id,
item_name,
item_desc,
'add'
FROM itemde
WHERE creation_date > (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT p_entity_type,
item_id,
item_name,
item_desc,
'update'
FROM itemde
WHERE creation_date < (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
ELSIF p_entity_type = NULL THEN
--Reading from org
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT entity_type,
org_id,
org_name,
org_desc,
'add'
FROM orgde
WHERE creation_date > (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT entity_type,
org_id,
org_name,
org_desc,
'update'
FROM orgde
WHERE creation_date < (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
--reading from item
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT entity_type,
item_id,
item_name,
item_desc,
'add'
FROM itemde
WHERE creation_date > (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
INSERT INTO dynamicentitygtt
(entity_type,
entity_id,
entity_code,
synonyms,
action)
SELECT entity_type,
item_id,
item_name,
item_desc,
'update'
FROM itemde
WHERE creation_date < (SELECT max_last_update_date
FROM batch_run_details
WHERE entity_type = p_entity_type);
END IF;
END IF;
END update_dynamic_entity;
La seconda cosa che farei è cambiare il nome di DYNAMICENTITYGTT in un nome leggibile, DYNAMIC_ENTITY_GTT. (in realtà lo codice in minuscolo. Lo mostro in maiuscolo perché è così che è nel dizionario dei dati. In realtà scrivo tutto il mio codice in minuscolo.)
Perché stai inserendo due righe quasi identiche in DYNAMICENTITYGTT ('add' e 'update')?
Il nome di quella tabella, con "GTT", suggerisce che si tratta di una tabella temporanea globale, quindi mi aspetto che tu faccia effettivamente qualcosa con essa, nella stessa sessione.
Puoi farlo in una sola istruzione inserto, se vuoi. Basta usare UNION ALLper incollare i risultati della query insieme. Con CASE WHENpuoi decidere se scrivere 'add'o 'update'.
Sto anche facendo alcune ipotesi qui:
- Non vuoi solo scrivere righe per
creation_dateminore o maggiore dimax_last_update_date, ma anche quando i due sono uguali . - Le righe copiate da
orgdedevono sempre avere entity_type'ORG'(non null quando p_entity_type è null). Lo stesso peritemdee'ITEM'. - Le righe copiate da
orgdedevono ottenere il flag'update'/ a'add'seconda di batch_run_details dove entity_type ='ORG'(non null quando p_entity_type è null). Lo stesso peritemdee'ITEM'.
La procedura:
create or replace procedure update_dynamic_entity
(
p_entity_type varchar2 default null,
p_update_mode varchar2
) is
begin
if upper(p_update_mode) = 'INCREMENTAL' then
insert into dynamicentitygtt (entity_type, entity_id, entity_code, synonyms, action)
select
'ORG', org_id, org_name, org_desc,
case when creation_date >
(select max_last_update_date from batch_run_details where entity_type = 'ORG')
then 'add'
else 'update'
end
from orgde
where upper(p_entity_type) = 'ORG' or p_entity_type is null
union all
select
'ITEM', item_id, item_name, item_desc,
case when creation_date >
(select max_last_update_date from batch_run_details where entity_type = 'ITEM')
then 'add'
else 'update'
end
from itemde
where upper(p_entity_type) = 'ITEM' or p_entity_type is null;
end if;
end update_dynamic_entity;
Se lo desideri meglio con istruzioni separate (cioè no UNION ALL), sposterei di nuovo le WHEREcondizioni al di fuori delle query:
if upper(p_update_mode) = 'INCREMENTAL' then
if upper(p_entity_type) = 'ORG' or p_entity_type is null then
insert into dynamicentitygtt (entity_type, entity_id, entity_code, synonyms, action)
...
from orgde;
end if;
if upper(p_entity_type) = 'ITEM' or p_entity_type is null then
insert into dynamicentitygtt (entity_type, entity_id, entity_code, synonyms, action)
...
from itemde;
end if;
end if;