Я совершенствую имеющийся у меня сценарий, чтобы его можно было автоматизировать и поддерживать конечными пользователями.
Ранее я упоминал часть этого скрипта в этот ТАК пост.
Как описывает Рэнди в его ответ, логика оператора SQL должна быть заменена комбинацией таблиц и объединений для достижения той же цели результат.
Основная ситуация и цель таковы:
В настоящее время скрипт автоматически назначает консультантов студентам на основе сложного набора правил, включающих несколько переменных.
Правила для терминальных сценариев будут со временем меняться из-за изменений в штате (нанятые/уволенные консультанты), специальностей (добавленные/удаленные программы) и ограничений по кредитным часам (минимальное количество часов, необходимое для выбора консультанта).
Эти правила должны поддерживаться вне сценария/SQL, чтобы конечные пользователи (деканы/руководители отделов) могли управлять сценариями терминала.
Для эффективного управления этими правилами необходимо создать пользовательскую таблицу.
Вот SQL, который в настоящее время используется для обеспечения соблюдения этих правил:
SELECT DISTINCT s.id stu_id,
stu_id.fullname stu_name,
p.major1 major,
p.minor1 minor,
s.reg_hrs,
NVL(st.cum_earn_hrs,0) ttl_hrs,
p.adv_id curr_adv_id,
adv_id.fullname curr_adv_name,
CASE WHEN (p.adv_id <> 35808 AND p.major1 = 'NS') THEN (1165)
WHEN (p.adv_id = 35808 AND p.major1 = 'NS') THEN (35808)
WHEN (p.adv_id = 9179 AND p.major1 = 'DART') THEN (9179)
WHEN (p.minor1 IN ('RT','RESP') AND st.cum_earn_hrs >= 24) THEN (70897)
WHEN (p.major1 IN ('CDSC','CDSD')) THEN (52125)
WHEN (p.major1 IN ('CA','CB')) THEN (24702)
WHEN (p.minor1 = 'NURS') THEN (51569)
WHEN (p.major1 = 'LEG') THEN (13324)
WHEN (p.major1 = 'CC') THEN (73837)
WHEN (p.major1 = 'CCRE') THEN (1133)
WHEN ((p.adv_id IN (SELECT DISTINCT id FROM fac_rec WHERE stat = 'I'))
OR (st.cum_earn_hrs < 24 AND (p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0 AND min_hrs >= 24))
OR (s.id NOT IN (SELECT DISTINCT stu.id FROM stu_acad_rec stu, sess_info si WHERE stu.yr = si.prev_yr AND stu.sess = si.prev_sess AND stu.reg_hrs > 0 AND stu.reg_stat IN ('C','R') AND stu.prog = 'UNDG'))
OR ((p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat <> 'A' OR max_stu <= 0))
OR ((p.adv_id||p.major1) NOT IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0)))
THEN (9238)
ELSE (p.adv_id)
END new_adv_id,
CASE WHEN (p.adv_id <> 35808 AND p.major1 = 'NS') THEN ('Deborah')
WHEN (p.adv_id = 35808 AND p.major1 = 'NS') THEN ('Veronica')
WHEN (p.adv_id = 9179 AND p.major1 = 'DART') THEN ('Stella')
WHEN (p.minor1 IN ('RT','RESP') AND st.cum_earn_hrs >= 24) THEN ('Lisa')
WHEN (p.major1 IN ('CDSC','CDSD')) THEN ('Joanne')
WHEN (p.major1 IN ('CA','CB')) THEN ('Barbara')
WHEN (p.minor1 = 'NURS') THEN ('Karen')
WHEN (p.major1 = 'LEG') THEN ('Nancy')
WHEN (p.major1 = 'CC') THEN ('Alberta')
WHEN (p.major1 = 'CCRE') THEN ('Naomi')
WHEN ((p.adv_id IN (SELECT DISTINCT id FROM fac_rec WHERE stat = 'I'))
OR (st.cum_earn_hrs < 24 AND (p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0 AND min_hrs >= 24))
OR (s.id NOT IN (SELECT DISTINCT stu.id FROM stu_acad_rec stu, sess_info si WHERE stu.yr = si.prev_yr AND stu.sess = si.prev_sess AND stu.reg_hrs > 0 AND stu.reg_stat IN ('C','R') AND stu.prog = 'UNDG'))
OR ((p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat <> 'A' OR max_stu <= 0))
OR ((p.adv_id||p.major1) NOT IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0)))
THEN ('Staff')
ELSE (adv_id.fullname)
END new_adv_name,
CASE WHEN (p.adv_id <> 35808 AND p.major1 = 'NS') THEN ('NS majors not assigned to Veronica go to Debbie')
WHEN (p.adv_id = 35808 AND p.major1 = 'NS') THEN ('NS majors stay with Veronica')
WHEN (p.adv_id = 9179 AND p.major1 = 'DART') THEN ('DART majors stay with Stella')
WHEN (p.minor1 IN ('RT','RESP') AND st.cum_earn_hrs >= 24) THEN ('RT-RESP minors go to Lisa')
WHEN (p.major1 IN ('CDSC','CDSD')) THEN ('CDSC-CDSD majors go to Joanne')
WHEN (p.major1 IN ('CA','CB')) THEN ('CA-CB majors go to Barbara')
WHEN (p.minor1 = 'NURS') THEN ('NURS minors go to Karen')
WHEN (p.major1 = 'LEG') THEN ('LEG majors go to Nancy')
WHEN (p.major1 = 'CC') THEN ('CC majors go to Alberta')
WHEN (p.major1 = 'CCRE') THEN ('CCRE majors go to Naomi')
WHEN (p.adv_id IN (SELECT DISTINCT id FROM fac_rec WHERE stat = 'I'))
THEN ('Current advisor is inactive')
WHEN (st.cum_earn_hrs < 24 AND (p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0 AND min_hrs >= 24))
THEN ('Total credits for this student did not meet the advisor reqs for this major')
WHEN (s.id NOT IN (SELECT DISTINCT stu.id FROM stu_acad_rec stu, sess_info si WHERE stu.yr = si.prev_yr AND stu.sess = si.prev_sess AND stu.reg_hrs > 0 AND stu.reg_stat IN ('C','R') AND stu.prog = 'UNDG'))
THEN ('This student did not attend '||si.prev_sess||si.prev_yr)
WHEN ((p.adv_id||p.major1) IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE (stat <> 'A' OR max_stu <= 0)))
THEN ('Current advisor is not advising students with this major')
WHEN ((p.adv_id||p.major1) NOT IN (SELECT DISTINCT (id||major) FROM adv_detail WHERE stat = 'A' AND max_stu > 0))
THEN ('Current advisor is not advising students with this major')
ELSE ('Student will stay with current advisor')
END change_comm
FROM stu_acad_rec s,
prog_enr_rec p,
OUTER stu_stat_rec st,
id_rec stu_id,
id_rec adv_id,
sess_info si
WHERE s.id = p.id
AND s.id = st.id
AND s.id = stu_id.id
AND p.adv_id = adv_id.id
AND s.yr = si.curr_yr
AND s.sess = si.curr_sess
AND s.reg_hrs > 0
AND s.reg_stat IN ('C','R')
AND s.prog = 'UNDG'
AND p.prog = 'UNDG'
AND st.prog = 'UNDG'
AND s.id NOT IN (3,287,9238,59999) {System test use IDs}
INTO TEMP stu_list
WITH NO LOG;
Я пытаюсь создать таблицу для хранения всех этих правил, но никогда не создавал таблицу с такой целью.
Моя идея до сих пор представляет собой таблицу с этой структурой:
adv_assign_rules
----------------
rule_no
curr_adv_id
major1
major2
minor1
minor2
cum_earn_hrs
new_adv_id
rule_desc
rule_no_ref
rule_stat
rule_date
Пример строки этой таблицы, которая будет соответствовать первому варианту выбора SQL, может выглядеть так:
rule_no 1
curr_adv_id !35808
major1 =NS
major2
minor1
minor2
cum_earn_hrs
new_adv_id 1165
rule_desc NS majors not assigned to 35808 go to Debbie
rule_no_ref
rule_stat A
rule_date 2011-09-26 15:02:26.000
Есть ли недостатки у такой таблицы? Может ли этот тип установки соответствовать всем этим правилам? Кто-нибудь знает, где найти примеры таблиц, используемых для аналогичных целей?
Я ищу предложения по улучшению или альтернативные решения этой проблемы. Сценарии «иначе» в этих заявлениях о случаях указывают на то, что никаких изменений в консультанте учащегося не требуется. Кроме того, в случае, который содержит наибольшее количество логики (последний случай перед случаем «else»), новый советник по умолчанию имеет значение 9238 — это указывает на то, что для назначения нового советника будет использоваться другая уже существующая логика. Все предыдущие случаи являются сценариями по умолчанию, которые являются особыми случаями, которые не следуют правилам назначения новых советников - это особые случаи, которые я пытаюсь воссоздать в формате таблицы.
ОБНОВЛЕНИЕ: я также ищу функциональность для воспроизведения и/или сценариев. Я добавил два поля с именами: rule_no
и rule_no_ref
, которые представляют собой серийный номер (автоинкремент) и ссылку на серийный номер другого правила соответственно.
Заранее благодарим за любую помощь, которая может быть предоставлена!
CASE
для этого. Будет трудно воспроизвести поведение короткого замыкания без какой-либо петли. Одна из возможностей — использовать динамический SQL и заполнить таблицуCASE
критериями для каждого сценария. - person JNK   schedule 27.09.2011