procedimiento plsql línea repetitiva de código. tratando de hacer de una mejor manera
Tengo un escenario. Si el usuario pasa el parámetro Entity_type
, debe insertar datos solo para ese entity
( table
). Si no pasa ningún parámetro, debe insertar datos para todas las tablas requeridas en una tabla.
entonces tenemos una tabla DYNAMICENTITYGTT
que tomará datos de la Item
tabla si se pasa, org
tabla si se pasa. Pero tomará datos de la tabla si el Entity_type
parámetro es nulo en proc ..
También almacenará otra columna dependiendo del tipo de UPDATE_MODE
medio que agregue o elimine. La tabla de destino es la misma. La tabla de origen y su nombre de columna son diferentes pero el tipo es el mismo.
He escrito a continuación el procedimiento para el mismo.
Solo estoy solicitando si hay alguna forma para mejorar este código. Quiero decir, ¿se puede escribir esto de una manera más inteligente? Porque estoy repitiendo varias líneas. He dado un ejemplo de 2 entidades pero hay 7, por lo que el código sería enorme.
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;
Respuestas
Básicamente veo dos inserciones con dos variables que determinan su contenido. Está insertando desde la declaración de selección, por lo tanto, puede manipular estas selecciones para no devolver valores cuando las condiciones no sean las esperadas.
Para el parámetro p_update_mode
es fácil, si contiene el valor "eliminar" insertar "eliminar", si contiene el valor "agregar" insertar "agregar".
Para el parámetro p_entity_type
, insertamos de ambas selecciones cuando su valor es "NULL", solo de la itemde
tabla si el valor es "ELEMENTO" y solo de la orgde
tabla si el valor es "ORG".
Ahora, en caso de que haya algún valor no válido en p_entity_type
ninguna de las selecciones, se producirán datos, ya que solo reconocemos "NULL", "ITEM" y "ORG". Pero para el parámetro p_update_mode
modificamos directamente el valor y lo usamos en la inserción, por lo tanto, sería mejor realizar alguna verificación si el valor de entrada es válido para nosotros.
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;
Mientras escribe, tiene 7 entidades, por lo tanto, este enfoque llevaría a tener 7 inserciones, ya que creo (y avíseme si me equivoco) cada entidad tiene su propio conjunto de datos en diferentes tablas.
También existe la posibilidad de unir todas estas tablas y convertirlas en una sola inserción como se muestra a continuación, y cada nueva entidad significaría solo agregar una nueva selección en WITH
parte de la declaración. Pero no estoy seguro del rendimiento en este caso. Eso dependería de lo llenas que estén tus mesas.
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;
E incluso si esto se complica para usted, puede crear un VIEW
lugar en el que haga las UNION
s y eliminarlo WITH
de PROCEDURE
y con nuevas entidades agregando selecciones en VIEW
lugar de PROCEDURE
.