Mengoptimalkan kode di PL / SQL. Membuatnya menjadi benar. Kode berjalan tetapi tidak sesuai
Saya memiliki 3 set tabel. Tabel sumber
ORGDE(ORG_ID,ORG_NAME,ORG_DESC,CREATION_DATE,LAST_UPDATE_DATE)
ITEMDE(ITEM_ID,ITEM_NAME,ITEM_DESC,CREATION_DATE,LAST_UPDATE_DATE)
Tabel target
DYNAMICENTITYGTT(ENTITY_TYPE,ENTITY_ID,ENTITY_CODE,SYNONYMS,ACTION)
Tabel kondisi
BATCH_RUN_DETAILS(ENTITY_TYPE,LAST_RUN_DATE,MAX_LAST_UPDATE_DATE)
Kami harus memasukkan data dalam DYNAMICENTITYGTT dari ORGDE dan ITEMDE. Action in DYNAMICENTITYGTT will be 'update' where CREATION_DATE>max_last_update_date
Action DYNAMICENTITYGTT will be 'add' where CREATION_DATE<max_last_update_date
jika p_entity_type ada maka itu akan memasukkan data untuk entitas itu yang lain akan disisipkan untuk kedua tabel.
Saya telah menulis kode di bawah ini. saya ingin memperbaikinya dan membuatnya lebih baik.
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;
Bisakah Anda menyarankan perbaikan pada kode.
Jawaban
Ini akan serupa dengan jawaban sebelumnya pada prosedur plsql baris kode berulang. mencoba membuatnya dengan cara yang lebih baik .
Apa yang kita lakukan sekarang adalah menambahkan JOIN
ke tabel yang berisi batch_run_details
dan kasus yang akan menentukan untuk setiap baris tindakan apa yang harus disisipkan berdasarkan creation_date
dan 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;
Dan hanya untuk menyelesaikan dari posting sebelumnya, versi sisipan tunggal juga:
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;
Hal pertama yang akan saya lakukan untuk memperbaikinya adalah memformatnya agar dapat dibaca. Saya membutuhkan lebih sedikit waktu untuk memformatnya daripada yang dibutuhkan untuk menulis kalimat ini:
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;
Hal kedua yang akan saya lakukan adalah mengubah nama DYNAMICENTITYGTT menjadi nama yang dapat dibaca, DYNAMIC_ENTITY_GTT. (sebenarnya kode itu dalam huruf kecil. Saya tunjukkan dalam huruf besar karena begitulah dalam kamus data. Saya sebenarnya menulis semua kode saya dalam huruf kecil.)
Mengapa Anda menyisipkan dua baris yang hampir identik ke DYNAMICENTITYGTT ('add', dan 'update')?
Nama tabel itu, dengan 'GTT' menunjukkan itu adalah Tabel Sementara Global, jadi saya berharap Anda benar-benar melakukan sesuatu dengannya, di sesi yang sama.
Anda dapat melakukan ini dalam satu pernyataan sisipan, jika Anda mau. Cukup gunakan UNION ALL
untuk merekatkan hasil kueri. Dengan CASE WHEN
Anda dapat memutuskan apakah akan menulis 'add'
atau 'update'
.
Saya juga membuat beberapa asumsi di sini:
- Anda tidak hanya ingin menulis baris
creation_date
kurang atau lebih besar darimax_last_update_date
, tetapi juga ketika keduanya sama . - Baris yang disalin dari
orgde
harus selalu memiliki jenis_itas'ORG'
(bukan null jika p_entity_type null). Sama untukitemde
dan'ITEM'
. - Baris yang disalin
orgde
akan mendapatkan'update'
/'add'
flag bergantung pada batch_run_details di mana entity_type ='ORG'
(bukan null jika p_entity_type null). Sama untukitemde
dan'ITEM'
.
Prosedur:
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;
Jika Anda menginginkan ini lebih baik dengan pernyataan terpisah (yaitu tidak UNION ALL
), saya akan memindahkan WHERE
kondisi di luar kueri lagi:
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;