Как поместить часть кода в виде строки в таблице, чтобы использовать ее в процедуре?
Я пытаюсь решить проблему ниже: мне нужно подготовить таблицу, которая состоит из 3 столбцов: user_id, значение месяца. Каждый из более чем 200 пользователей имеет различные значения параметров, которые определяют ожидаемое значение, а именно: LOB, CHANNEL, SUBSIDIARY. Поэтому я решил сохранить его в таблице ASYSTENT_GOALS_SET. Но я хотел избежать умножения строк и подумал, что было бы неплохо поместить все условия как часть кода, который я буду использовать в предложении "где" далее в процедуре. Итак, в качестве примера - вместо нескольких строк:
Я создал такую запись:
До сих пор я создал таблицу тестирования ASYSTENT_TEST (где я собираю месяц и значение для определенного пользователя). Я написал часть процедуры, где я использовал BULK COLLECT.
declare
type test_row is record
(
month NUMBER,
value NUMBER
);
type test_tab is table of test_row;
BULK_COLLECTOR test_tab;
p_lob varchar2(10) :='GOSP';
p_sub varchar2(14);
p_ch varchar2(10) :='BR';
begin
select subsidiary into p_sub from ASYSTENT_GOALS_SET where user_id='40001001';
execute immediate 'select mc, sum(ppln_wartosc) plan from prod_nonlife.mis_report_plans
where report_id = (select to_number(value) from prod_nonlife.view_parameters where view_name=''MIS'' and parameter_name=''MAX_REPORT_ID'')
and year=2017
and month between 7 and 9
and ppln_jsta_symbol in (:subsidiary)
and dcs_group in (:lob)
and kanal in (:channel)
group by month order by month' bulk collect into BULK_COLLECTOR
using p_sub,p_lob,p_ch;
forall x in BULK_COLLECTOR.first..BULK_COLLECTOR.last insert into ASYSTENT_TEST values BULK_COLLECTOR(x);
end;
Так что теперь, когда в столбце таблицы ASYSTENT_GOALS_SET SUBSIDIARY (varchar) содержится строка 12_00_00 (которая является кодом одного из дочерних), все работает нормально. Но проблема в том, что пользователь работает в двух дочерних компаниях, скажем, 12_00_00 и 13_00_00. Я понятия не имею, как записать это. Если столбец SUBSIDIARY состоит из: "12_00_00","13_00_00" или "12_00_00","13_00_00" или, возможно, 12_00_00 "," 13_00_00, я пробовал множество вариантов после поиска по темам, таким как "Удаление с одним / выходом / двойным qoutes". Может быть, я должен что-то изменить в немедленном исполнении?
Или, может быть, мой подход к этому вопросу совершенно неверен с самого начала (надеюсь, нет:)). Буду благодарен за поддержку.
2 ответа
Я не создавал описанную здесь табличную функцию, но эта статья вдохновила меня вернуться, чтобы попробовать regexp_substr
функционировать снова.
Я изменился: ppln_jsta_symbol in (:subsidiary)
в ppln_jsta_symbol in (select regexp_substr((select subsidiary from ASYSTENT_GOALS_SET where user_id=''fake_num''),''[^,]+'', 1, level) from dual
connect by regexp_substr((select subsidiary from ASYSTENT_GOALS_SET where user_id=''fake_num''), ''[^,]+'', 1, level) is not null)
Теперь это работает как шарм! Большое спасибо @Dessma за потраченное время и предложение!
"Я хотел избежать умножения строк и подумал, что было бы неплохо поместить все условия как часть кода, который я буду использовать в предложении" где "далее в процедуре"
Это кажется ошибочным требованием. Не беспокойтесь о количестве строк: базы данных оптимизированы для хранения и извлечения строк.
Что они не умеют делать, так это иметь дело с "многозначными" столбцами. Как показывает ваше собственное решение, оно не очень хорошее, оно очень далеко от хорошего, на самом деле это полная боль в шее. Отныне каждый раз, когда кому-то нужно работать с subsidiary
им придется вызывать функцию. Добавить, изменить или удалить дочернюю компанию гораздо сложнее, чем следовало бы. Также нет возможности обеспечить целостность данных, т. Е. Проверить, что дочерняя компания действительна в отношении справочной таблицы.
Может быть, все это не имеет значения для вас. Но есть очень веские причины, по которым Кодд назначил "не повторяющиеся группы" в качестве критерия первой нормальной формы, основного шага построения надежной модели данных.
Правильным решением, лучшим в отрасли на протяжении почти сорока лет, было бы признание того, что ВСПОМОГАТЕЛЬНЫЙ существует с гранулярностью, отличной от CHANNEL, и поэтому должен храниться в отдельной таблице.