Нужна помощь в разработке таблицы правил, которые будут использоваться для выбора SQL

Я совершенствую имеющийся у меня сценарий, чтобы его можно было автоматизировать и поддерживать конечными пользователями.

Ранее я упоминал часть этого скрипта в этот ТАК пост.

Как описывает Рэнди в его ответ, логика оператора 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, которые представляют собой серийный номер (автоинкремент) и ссылку на серийный номер другого правила соответственно.

Заранее благодарим за любую помощь, которая может быть предоставлена!


person CheeseConQueso    schedule 26.09.2011    source источник
comment
Я думаю, вы можете оставить CASE для этого. Будет трудно воспроизвести поведение короткого замыкания без какой-либо петли. Одна из возможностей — использовать динамический SQL и заполнить таблицу CASE критериями для каждого сценария.   -  person JNK    schedule 27.09.2011
comment
Я бы сохранил его, если бы я был единственным, кто намеревался его поддерживать, но конечным пользователям нужен способ настроить эти правила. я рассмотрю ваше другое предложение - спасибо   -  person CheeseConQueso    schedule 27.09.2011


Ответы (1)


Я бы обошёл это немного иначе:

1) Создайте таблицу rule_type

id 
name 

2) Создайте таблицу rule_set

id   -- rule 
type -- relation to talbe 1
name 
staff_group -- relation to the appropriate staff group for that rule
student_group  -- relation to the appropriate student group for that rule
val_int --- for the rules that require numeric number
val_chr --- for rules that require integer values
val_date --- for date values rules
date_start --- start date of a rule
date_end  --- end date of a rule

вы также можете создавать поля для интервальных параметров, таких как целочисленный диапазон от X ... Y, например: val_int_start val_int_end или для любого другого типа данных в этом отношении

затем создайте процедуру хранения, которая будет обрабатывать правила и оценивать соответствующие данные

Хорошая мысль об этом подходе заключается в том, что вам действительно редко понадобится кодировать что-то новое в долгосрочной перспективе.

person Jester    schedule 09.10.2011
comment
спасибо за ответ ... дело в том, что это не учитывает атрибуты сравнения (например: ‹› ›= ‹= ==), а также не определяет, какие поля сравнивать - person CheeseConQueso; 18.10.2011