plsql prosedur baris kode berulang. mencoba membuatnya dengan cara yang lebih baik

Aug 21 2020

Saya punya skenario. Jika pengguna melewatkan parameter Entity_typemaka Anda perlu memasukkan data hanya untuk itu entity( table). Jika dia tidak melewatkan parameter apa pun, maka Anda perlu memasukkan data untuk semua tabel yang diperlukan ke dalam satu tabel.

Jadi kami memiliki tabel DYNAMICENTITYGTTyang akan mengambil data dari Itemtabel jika dilewatkan, orgtabel jika dilewatkan. Tapi itu akan mengambil data dari kedua tabel jika Entity_typeparameter null di proc ..

Juga itu akan menyimpan kolom lain tergantung pada jenis UPDATE_MODEsarana tambah atau hapus. Tabel target sama. tabel sumber dan nama kolomnya berbeda tetapi jenisnya sama.

Saya telah menulis di bawah prosedur untuk hal yang sama.

Saya hanya meminta apakah ada cara untuk membuat kode ini lebih baik. Maksud saya, bisakah ini ditulis dengan cara yang lebih cerdas? Karena saya mengulang beberapa baris. Saya telah memberikan contoh 2 entitas tetapi ada 7 jadi kode akan menjadi sangat besar.

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;

Jawaban

1 KayaNatsumi Aug 20 2020 at 22:10

Pada dasarnya saya melihat dua sisipan dengan dua variabel yang menentukan isinya. Anda memasukkan dari pernyataan pilih, oleh karena itu Anda dapat memanipulasi pemilihan ini untuk tidak mengembalikan nilai ketika kondisi tidak seperti yang diharapkan.

Untuk parameternya p_update_modemudah saja, jika mengandung nilai "delete" masukkan "delete", jika mengandung nilai "add" insert "add".

Untuk parameter p_entity_typekita masukkan dari kedua pilihan ketika nilainya "NULL", hanya dari itemdetabel jika nilainya "ITEM" dan hanya dari orgdetabel jika nilainya "ORG".

Sekarang jika ada beberapa nilai yang tidak valid tidak p_entity_typesatupun dari pilihan akan menghasilkan data karena kami hanya mengenali "NULL", "ITEM" dan "ORG". Namun untuk parameter p_update_modekita langsung memodifikasi nilainya dan menggunakannya di insert, oleh karena itu sebaiknya dilakukan beberapa pengecekan apakah nilai input tersebut valid untuk kita.

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;

Saat Anda menulis, Anda memiliki 7 entitas oleh karena itu pendekatan ini akan menghasilkan 7 sisipan, seperti yang saya percaya (dan beri tahu saya jika saya salah) setiap entitas memiliki kumpulan datanya sendiri dalam tabel yang berbeda.

Ada juga kemungkinan untuk menggabungkan semua tabel ini dan membuatnya menjadi satu sisipan seperti contoh di bawah ini, dan setiap entitas baru berarti hanya menambahkan pilih baru ke dalam WITHbagian dari pernyataan. Tetapi saya tidak yakin dengan kinerja dalam kasus ini. Itu akan tergantung pada seberapa penuh tabel Anda.

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;

Dan bahkan jika ini menjadi berantakan untuk Anda, Anda dapat membuat VIEWtempat Anda melakukan UNIONs dan menghapusnya WITHdari PROCEDUREdan dengan entitas baru menambahkan pilihan ke VIEWdaripada PROCEDURE.