Trennen von Regeln und PL/SQL-Code Version 9, 05.05.04 Armin Singer Semantec GmbH, Germany
Wo finden wir Regeln? Business Rules stecken z.b. in PL/SQL Code Warum sollten Regeln von Programmcode getrennt werden? Prinzip: Separation of Concerns! Spezialisierung Was sind die Vorteile????
PL/SQL Code (1): PROCEDURE ICIS_Faell_datum_ermitteln ( p_vvs_begin IN DATE, /* Vertragsversionsbeginndatum */ p_aenderungstyp IN VARCHAR2, /* Änderungstyp der Deckung */ p_zws_code IN varchar2, /* Code für Zahlweise */ p_hauptfaelligkeit IN DATE, /* Hauptfälligkeit */ p_dpr_typ IN VARCHAR2, /* DPR-TYP */ p_datum_von IN DATE, /* Datum, ab dem erhoben wird */ p_datum_bis IN DATE, /* Datum, bis zu dem erhoben wird */ p_abr_in_monate IN NUMBER, /* Monatskennzeichen aus ZBD */ p_anz_monate IN NUMBER, /* Anzahl Monate gemäß p_zws_code (Falls 99 >> =0)*/ p_datum_faellig IN OUT DATE, /* Datum, an dem abgerechnet wird */ p_fpr_batch_entitaet IN OUT VARCHAR2, p_fpr_auspraegung IN OUT VARCHAR2, p_fpr_feh_fehlercode IN OUT VARCHAR2, p_fpr_fehlertext IN OUT VARCHAR2, p_returncode IN OUT NUMBER) IS /* Returncode der Prozedur */ /* Ermittlung des Fälligkeitsdatums gemäß Funktionsbeschreibung 9834a in der Fassung vom 2.10.1997 mw, 6.10.1997 mw, 25.11.1997 keine Sonderbehandlung für monatliche Zahlweise */ F_ORACLE CONSTANT NUMBER(1) := -2; F_SACH CONSTANT NUMBER(1) := -3; v_tagesdatum DATE; v_fr_erh_datum DATE; v_plus_monate NUMBER(2); BEGIN p_datum_faellig := TO_DATE ('01.01.1990', 'dd.mm.yyyy'); p_returncode := 0; v_tagesdatum := sysd_te; IF ( p_zws_code IN ('0', '99') OR p_dpr_typ = 'EP') -- Einmalprämie p_datum_faellig := v_tagesdatum;
PL/SQL Code (2): ELSIF p_zws_code = '81' --20020313_029HK: Neue Zahlweise berücksichtigen -- Projektprämie IF p_datum_von < v_tagesdatum p_datum_faellig := v_tagesdatum; ELSE p_datum_faellig := p_datum_von; END IF; --20020313_029HK: --20020313_029HK: -- monatliche Zahlweise --20020313_029HK: ELSIF p_zws_code = '88' --20020313_029HK: IF p_datum_von < v_tagesdatum --20020313_029HK: --20020313_029HK: p_datum_faellig := v_tagesdatum; --20020313_029HK: ELSE --20020313_029HK: p_datum_faellig := p_datum_von; --20020313_029HK: END IF; ELSIF p_zws_code IN ('1', '2', '4', '12') -- ganz-, halb, viertel-jährliche ZW v_plus_monate := ROUND (12 / p_anz_monate); IF p_aenderungstyp = '7' -- Folge p_datum_faellig := ADD_MONTHS (p_datum_von, NVL(p_abr_in_monate, 0)); ELSE -- Neuanlage, Änderungen /* Ermittlung des frühesten Erhebungsdatums */ v_fr_erh_datum := TO_DATE (LTRIM (TO_CHAR (p_hauptfaelligkeit, 'DDMM')) LTRIM (TO_CHAR (p_vvs_begin, 'YYYY')), 'DDMMYYYY'); -- HF im Versicherungsbeginnjahr IF v_fr_erh_datum > p_vvs_begin v_fr_erh_datum := ADD_MONTHS (v_fr_erh_datum, -12); END IF;
PL/SQL Code (3): WHILE v_fr_erh_datum <= ADD_MONTHS (p_vvs_begin, 0 - v_plus_monate) LOOP v_fr_erh_datum := ADD_MONTHS (v_fr_erh_datum, v_plus_monate); END LOOP; v_fr_erh_datum := ADD_MONTHS (v_fr_erh_datum, NVL(p_abr_in_monate,0)); IF p_datum_von < v_fr_erh_datum IF v_fr_erh_datum > v_tagesdatum p_datum_faellig := v_fr_erh_datum; ELSE p_datum_faellig := v_tagesdatum; END IF; ELSE IF p_datum_von > v_tagesdatum p_datum_faellig := p_datum_von; ELSE p_datum_faellig := v_tagesdatum; END IF; END IF; END IF; ELSE p_returncode := F_SACH; p_fpr_batch_entitaet := 'Faelligkeitsdatum'; p_fpr_fehlertext := 'Zahlweise nicht definiert!'; RETURN; END IF; EXCEPTION WHEN OTHERS p_returncode := F_ORACLE; p_fpr_batch_entitaet := 'Faelligkeitsdatum'; p_fpr_auspraegung := NULL; p_fpr_feh_fehlercode := 'ORA-' to_char(sqlcode); p_fpr_fehlertext := SQLERRM; RETURN; END ICIS_Faell_datum_ermitteln;
1. Programmcode analysieren 2. Entscheidungstabelle erstellen 3. Toolunterstützte Validierung&Verifizierung 4. Entscheidungsbaum erstellen (Tool) 5. Vergleich: Entcheidungsbaum - Code 6. Generierung und Optimierung der Regeln 7. Ersetzen des Codes durch einen Aufruf der Business Rules Engine
1. Analyze code Bedingungen Aktionen 1. Due today 2. Due latest among (today, charge_starting_date) 3. Due charge_starting_date + months_to_billing 4. Due latest among (today, charge_starting_date, next_periodic_date)
2. Entscheidungstabelle erstellen komplett optimiert
3. V & V Report
4.+ 5. Entscheidungsbaum
6. Generate and optimize rules (a)
6. Generate and optimize rules (b) If type_of_coverage is "single premium" Then update due_date to today If mode_of_billing is "once Then update due_date to today If mode_of_billing is "project_premium Then update due_date to latest among (today, charge_starting_date) If mode_of_billing is "periodic and change is automatic Then update due_date to charge_starting_date + months_to_billing If mode_of_billing is "periodic and change isn t automatic Then update due_date to latest among (today, charge_starting_date, next_periodic_date + months_to_billing)
6. Generate and optimize rules (c)
7.Replace code by calls to Business Rules Repository (b) PROCEDURE ICIS_Faell_datum_ermitteln ( p_vvs_begin IN DATE, /* Vertragsversionsbeginndatum */ p_aenderungstyp IN VARCHAR2, /* Änderungstyp der Deckung */ p_zws_code IN varchar2, /* Code für Zahlweise */ p_hauptfaelligkeit IN DATE, /* Hauptfälligkeit */ p_dpr_typ IN VARCHAR2, /* DPR-TYP */ p_datum_von IN DATE, /* Datum, ab dem erhoben wird */ p_datum_bis IN DATE, /* Datum, bis zu dem erhoben wird */ p_abr_in_monate IN NUMBER, /* Monatskennzeichen aus ZBD */ p_anz_monate IN NUMBER, /* Anzahl Monate gemäß p_zws_code (Falls 99 >> =0)*/ p_datum_faellig IN OUT DATE, /* Datum, an dem abgerechnet wird */ p_fpr_batch_entitaet IN OUT VARCHAR2, p_fpr_auspraegung IN OUT VARCHAR2, p_fpr_feh_fehlercode IN OUT VARCHAR2, p_fpr_fehlertext IN OUT VARCHAR2, p_returncode IN OUT NUMBER) IS input_data = BR_interface.input_data; output_data = BR_interface.output_data; BEGIN BR_interface.Map_input_data (input_data "Contract", "beginning_of_new_version", p_vvs_begin, "automatic_change", p_aenderungstyp, "mode_of_billing", p_zws_code, "single_premium", p_dpr_typ, "beginning_of_new_version", p_datum_von, "months_to_billing", p_abr_in_monate, "next_periodic_date", v_fr_erh_datum); BR_Interface.DSR (input_data, output_data); BR_interface.Map_output_data (output_data, "Contract", "due_date", due_date); END ICIS_Faell_datum_ermitteln;
Was sind die Vorteile? Wiederverwendbarkeit Lesbarkeit: Kein Coding / Decoding! Anwendungen erklären sich Management (Historie, Zugriff, Release, Vergleiche, Abhängigkeiten,..) Separat pflegbar Time to Market Konsistente Durchsetzung von Geschäftsregeln und Ausnahmen Wissenskonservierung Systemische Validierung und Verifizierung Drastisch Reduzierte Pflegekosten