plsql процедура повторяющаяся строка кода. пытаясь сделать лучше
У меня есть сценарий. Если пользователь передает параметр, Entity_type
вам нужно вставить данные только для этого entity
( table
). Если он не передает ни одного параметра, вам нужно вставить данные для всех необходимых таблиц в одну таблицу.
Итак, у нас есть таблица, DYNAMICENTITYGTT
которая будет брать данные из Item
таблицы, если она передана, org
таблица, если она передана. Но он будет брать данные из обеих таблиц, если в процессе Entity_type
параметр имеет значение null.
Также он будет хранить другой столбец в зависимости от типа UPDATE_MODE
средств добавления или удаления. Целевая таблица такая же. Исходная таблица и имя ее столбца отличаются, но тип одинаков.
Я написал ниже процедуру для того же.
Я всего лишь прошу, есть ли способ улучшить этот код. Я имею в виду, можно ли это написать более умным способом? Потому что я повторяю несколько строк. Я привел пример двух сущностей, но их семь, поэтому код будет огромным.
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;
Ответы
В основном я вижу две вставки с двумя переменными, определяющими его содержимое. Вы вставляете из оператора select, поэтому вы можете манипулировать этими выборками, чтобы не возвращать значения, когда условия не соответствуют ожидаемым.
Для параметра p_update_mode
это просто, если он содержит значение «удалить» вставить «удалить», если он содержит значение «добавить» вставить «добавить».
Для параметра p_entity_type
мы вставляем оба выбора, когда его значение равно «NULL», только из itemde
таблицы, если значение равно «ITEM», и только из orgde
таблицы, если значение равно «ORG».
Теперь, если есть какое-то недопустимое значение, p_entity_type
ни один из выборок не приведет к получению данных, поскольку мы распознаем только «NULL», «ITEM» и «ORG». Но для параметра p_update_mode
мы напрямую изменяем значение и используем его во вставке, поэтому было бы лучше выполнить некоторую проверку, действительно ли введенное значение для нас.
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;
Когда вы пишете, у вас есть 7 сущностей, поэтому этот подход приведет к 7 вставкам, поскольку я считаю (и дайте мне знать, если я ошибаюсь) каждая сущность имеет свой собственный набор данных в разных таблицах.
Существует также возможность объединить все эти таблицы и превратить их в одну вставку, как в примере ниже, и каждая новая сущность будет означать только добавление нового выбора в WITH
часть оператора. Но я не уверен в производительности в этом случае. Это будет зависеть от того, насколько заполнены ваши столы.
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;
И даже если это станет для вас запутанным, вы можете создать область, в VIEW
которой вы выполняете UNION
операции, и удалить ее WITH
из PROCEDURE
новых сущностей, добавляя выборки VIEW
вместо PROCEDURE
.