Ich versuche, die Geschäftslogik einer Intranet-C # -Webanwendung in der Datenbank zu duplizieren, damit andere Datenbanken darauf zugreifen und nach denselben Regeln arbeiten können. Diese "Regel" scheint ohne Hacks schwierig zu implementieren zu sein.
CREATE TABLE CASE_STAGE
(
ID NUMBER(9) PRIMARY KEY NOT NULL,
STAGE_ID NUMBER(9) NOT NULL,
CASE_PHASE_ID NUMBER(9) NOT NULL,
DATE_CREATED TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP NOT NULL,
END_REASON_ID NUMBER(9),
PREVIOUS_CASE_STAGE_ID NUMBER(9),
"CURRENT" NUMBER(1) NOT NULL,
DATE_CLOSED TIMESTAMP(6) DEFAULT NULL
);
und
CREATE TABLE CASE_RECOMMENDATION
(
CASE_ID NUMBER(9) NOT NULL,
RECOMMENDATION_ID NUMBER(9) NOT NULL,
"ORDER" NUMBER(9) NOT NULL,
DATE_CREATED TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP NOT NULL,
CASE_STAGE_ID NUMBER(9) NOT NULL
);
ALTER TABLE CASE_RECOMMENDATION ADD (
CONSTRAINT SYS_C00000
PRIMARY KEY
(CASE_ID, RECOMMENDATION_ID));
Die Geschäftslogik kann wie folgt zusammengefasst werden
When Inserting into CASE_STAGE
If CASE_STAGE.STAGE_ID = 1646
THEN
CASE_STAGE.PREVIOUS_STAGE_ID must be found in CASE_RECOMMENDATION.CASE_STAGE_ID
Kann diese Logik in einer Check-Einschränkung enthalten sein oder ist ein hässlicher Trigger der einzige Weg?
Bearbeiten:
- Für alle Werte von CASE_STAGE.STAGE_ID muss der Wert für PREVIOUS_STAGE_ID in CASE_STAGE.ID gefunden werden
- Die Anwendung erlaubt keine Löschungen aus CASE_RECOMMENDATION, wenn sie nicht mehr CURRENT ist (dh wenn der Wert von CASE_STAGE.CURRENT 0 ist, ist diese Stufe geschlossen und kann nicht mehr geändert werden, wenn = 1, ist dies die Stufe oder Zeile, die aktiv ist und kann jetzt geändert werden.)
Bearbeiten: Die Verwendung all der hervorragenden Ideen und Kommentare hier ist eine funktionierende Lösung für dieses Problem
CREATE MATERIALIZED VIEW LOG ON CASE_STAGE
TABLESPACE USERS
STORAGE (
BUFFER_POOL DEFAULT
)
NOCACHE
LOGGING
NOPARALLEL
WITH ROWID;
CREATE MATERIALIZED VIEW LOG ON CASE_RECOMMENDATION
TABLESPACE USERS
STORAGE (
BUFFER_POOL DEFAULT
)
NOCACHE
LOGGING
NOPARALLEL
WITH ROWID;
CREATE MATERIALIZED VIEW CASE_RECOMMENDATION_MV REFRESH FAST ON COMMIT AS
SELECT
cr.ROWID cr_rowid, --necessary for fast refresh
cs.ROWID cs_rowid, --necessary for fast refresh
cr.case_id,
cs.stage_id,
cr.recommendation_id
cr.case_stage_id,
cs.previous_case_stage_id
FROM CASE_RECOMMENDATION cr,
case_stage cs
WHERE cs.previous_case_stage_id = cr.case_stage_id (+)
AND CS.PREVIOUS_CASE_STAGE_ID IS NOT NULL
AND EXTRACT (YEAR FROM CS.DATE_CREATED) > 2010 --covers non conforming legacy data
AND CR.RECOMMENDATION_ID IS NULL
AND cs.stage_id =1646;
--this last line excludes everything but problem cases due to the outer join
ALTER TABLE CASE_RECOMMENDATION_MV ADD CONSTRAINT CASE_RECOMMENDATION_ck CHECK (
(previous_case_stage_id IS NOT NULL AND case_stage_id IS NOT NULL)
);
Beim Einfügen einer 1646-Stufe unter Verwendung vorhandener Pakete ohne Empfehlung war der Fehler
ORA-12008: error in materialized view refresh path
ORA-02290: check constraint (APPBASE.CASE_RECOMMENDATION_MV_C01) violated
ORA-06512: at line 49
Job erledigt! Nicht wofür eine materialisierte Ansicht gedacht war, sondern besser als ein Auslöser.
1646? Ist es eine Option, das Design zu ändern (Tabelle in zwei Teile zu teilen)?
CASE_RECOMMENDATION.CASE_STAGE_IDeinzigartig?