procédure plsql ligne de code répétitive. essayer de faire mieux
J'ai un scénario. Si l'utilisateur transmet le paramètre, Entity_typevous devez insérer des données pour cela entity( table) uniquement. S'il ne transmet aucun paramètre, vous devez insérer les données de toutes les tables requises dans une seule table.
donc Nous avons une table DYNAMICENTITYGTTqui prendra les données de la Itemtable si elle est passée, orgtable si elle est passée. Mais il prendra les données à la fois de la table si le Entity_typeparamètre est nul dans proc ..
En outre, il stockera une autre colonne en fonction du type de UPDATE_MODEmoyen d'ajouter ou de supprimer. La table cible est la même. la table source et son nom de colonne sont différents mais le type est le même.
J'ai écrit ci-dessous la procédure pour la même chose.
Je demande seulement s'il y a de toute façon pour améliorer ce code. Je veux dire, cela peut-il être écrit de manière plus intelligente? Parce que je répète plusieurs lignes. J'ai donné l'exemple de 2 entités mais il y en a 7, donc le code serait énorme.
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;
Réponses
Fondamentalement, je vois deux insertions avec deux variables déterminant son contenu. Vous insérez à partir d'une instruction select, vous pouvez donc manipuler ces sélections pour ne renvoyer aucune valeur lorsque les conditions ne sont pas celles attendues.
Pour le paramètre p_update_modec'est facile, s'il contient la valeur "supprimer" insérer "supprimer", s'il contient la valeur "ajouter" insérer "ajouter".
Pour le paramètre, p_entity_typenous insérons à partir des deux sélections lorsque sa valeur est "NULL", uniquement à partir de la itemdetable si la valeur est "ITEM" et uniquement à partir de la orgdetable si la valeur est "ORG".
Maintenant, au cas où il y aurait une valeur invalide dans p_entity_typeaucune des sélections, cela produira des données car nous ne reconnaissons que "NULL", "ITEM" et "ORG". Mais pour le paramètre, p_update_modenous modifions directement la valeur et l'utilisons dans insert, il serait donc préférable de vérifier si la valeur d'entrée est valide pour nous.
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;
Au moment où vous écrivez, vous avez 7 entités, donc cette approche conduirait à avoir 7 inserts, car je crois (et faites-moi savoir si je me trompe) chaque entité a son propre ensemble de données dans différentes tables.
Il est également possible de joindre toutes ces tables et d'en faire une seule insertion comme exemple ci-dessous, et chaque nouvelle entité signifierait seulement ajouter une nouvelle sélection dans une WITHpartie de l'instruction. Mais je ne suis pas sûr des performances dans ce cas. Cela dépendra du niveau de remplissage de vos tables.
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;
Et même si cela devient compliqué pour vous, vous pouvez créer un VIEWendroit où vous faites le UNIONs et le supprimer WITHde PROCEDUREet avec de nouvelles entités en ajoutant des sélections à la VIEWplace de PROCEDURE.