Code in PL / SQL optimieren. Machen Sie es richtig. Code läuft, ist aber nicht richtig
Ich habe 3 Tische. Quelltabelle
ORGDE(ORG_ID,ORG_NAME,ORG_DESC,CREATION_DATE,LAST_UPDATE_DATE)
ITEMDE(ITEM_ID,ITEM_NAME,ITEM_DESC,CREATION_DATE,LAST_UPDATE_DATE)
Zieltabelle
DYNAMICENTITYGTT(ENTITY_TYPE,ENTITY_ID,ENTITY_CODE,SYNONYMS,ACTION)
Konditionstabelle
BATCH_RUN_DETAILS(ENTITY_TYPE,LAST_RUN_DATE,MAX_LAST_UPDATE_DATE)
Wir müssen Daten aus ORGDE und ITEMDE in DYNAMICENTITYGTT einfügen. Aktion in DYNAMICENTITYGTT will be 'update' where CREATION_DATE>max_last_update_dateAktion DYNAMICENTITYGTT will be 'add' where CREATION_DATE<max_last_update_dateWenn p_entity_type vorhanden ist, werden Daten für diese Entität eingefügt, andernfalls werden Daten für beide Tabellen eingefügt.
Ich habe unten Code geschrieben. Ich möchte es verbessern und verbessern.
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;
Können Sie bitte eine Verbesserung des Codes vorschlagen?
Antworten
Dies wäre ähnlich wie bei der vorherigen Codezeile der plsql-Prozedur. versuchen, besser zu machen .
Was wir jetzt tun, ist das Hinzufügen JOINzu einer Tabelle, die einen batch_run_detailsFall enthält, der für jede Zeile bestimmt, welche Aktion basierend auf creation_dateund eingefügt werden muss 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;
Und nur zur Vervollständigung aus dem vorherigen Beitrag, Single-Insert-Version:
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;
Das erste, was ich tun würde, um es zu verbessern, ist es so zu formatieren, dass es lesbar ist. Ich habe weniger Zeit gebraucht, um es zu formatieren, als es nötig war, um diesen Satz zu schreiben:
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;
Als zweites würde ich den Namen von DYNAMICENTITYGTT in einen lesbaren Namen ändern, DYNAMIC_ENTITY_GTT. (Codiere es tatsächlich in Kleinbuchstaben. Ich zeige es in Großbuchstaben, weil es so im Datenwörterbuch ist. Ich schreibe tatsächlich meinen gesamten Code in Kleinbuchstaben.)
Warum fügen Sie zwei nahezu identische Zeilen in DYNAMICENTITYGTT ein ('add' und 'update')?
Der Name dieser Tabelle mit 'GTT' deutet darauf hin, dass es sich um eine globale temporäre Tabelle handelt. Ich würde also erwarten, dass Sie in derselben Sitzung tatsächlich etwas damit tun.
Sie können dies in einer Einfügeanweisung tun, wenn Sie möchten. Verwenden Sie einfach UNION ALL, um die Abfrageergebnisse zusammenzukleben. Mit können CASE WHENSie entscheiden, ob Sie schreiben 'add'oder 'update'.
Ich mache hier auch einige Annahmen:
- Sie möchten nicht nur Zeilen für
creation_dateweniger oder mehr als schreibenmax_last_update_date, sondern auch, wenn beide gleich sind . - Zeilen, aus denen kopiert wurde,
orgdemüssen immer den Entitätstyp haben'ORG'(nicht null, wenn p_entity_type null ist). Gleiches gilt füritemdeund'ITEM'. - Von kopierte Zeilen
orgdeerhalten das Flag'update'/ in'add'Abhängigkeit von batch_run_details, wobei entity_type ='ORG'(nicht null, wenn p_entity_type null ist). Gleiches gilt füritemdeund'ITEM'.
Der Ablauf:
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;
Wenn Sie dies mit separaten Anweisungen (dh nein UNION ALL) besser möchten, würde ich die WHEREBedingungen erneut außerhalb der Abfragen verschieben:
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;