YKPN#79783 Ondersteuning van sensorlimieten

svn path=/Database/trunk/; revision=61638
This commit is contained in:
Peter Feij
2023-08-30 09:46:38 +00:00
parent a505fee404
commit bd3131a87b
2 changed files with 186 additions and 44 deletions

View File

@@ -15,8 +15,7 @@ CREATE OR REPLACE PACKAGE ins AS
FUNCTION state_compare (str1 IN VARCHAR, str2 IN VARCHAR) RETURN NUMBER;
FUNCTION state_diff (str1 IN VARCHAR, str2 IN VARCHAR) RETURN NUMBER;
FUNCTION state_thresholdcompare (pdeel_key IN NUMBER, pdays NUMBER DEFAULT NULL) RETURN NUMBER;
PROCEDURE compress_states (today IN DATE DEFAULT SYSDATE);
PROCEDURE ins_daily(today IN DATE DEFAULT SYSDATE);
PROCEDURE compress_states (puntildate IN DATE DEFAULT SYSDATE-1);
END ins;
/
@@ -409,14 +408,14 @@ CREATE OR REPLACE PACKAGE BODY ins AS
IF pdays IS NULL
THEN
SELECT ins_deel_state, ins_srtdeel_statethreshold
INTO lstate, lstatedate, lstatethreshold
INTO lstate, lstatethreshold
FROM ins_deel d, ins_srtdeel sd
WHERE d.ins_srtdeel_key = sd.ins_srtdeel_key
AND ins_deel_verwijder IS NULL
AND d.ins_deel_key = pdeel_key;
ELSE
SELECT ins_deel_state, ins_srtdeel_statethreshold
INTO lstate, lstatedate, lstatethreshold
INTO lstate, lstatethreshold
FROM ins_deel d, ins_srtdeel sd
WHERE d.ins_srtdeel_key = sd.ins_srtdeel_key
AND ins_deel_verwijder IS NULL
@@ -435,7 +434,7 @@ CREATE OR REPLACE PACKAGE BODY ins AS
RETURN retval;
END;
PROCEDURE compress_states(today IN DATE DEFAULT SYSDATE)
PROCEDURE compress_states(puntildate IN DATE DEFAULT SYSDATE-1)
AS
CURSOR c_days(eerste_dag IN DATE, laatste_dag IN DATE)
IS
@@ -520,14 +519,14 @@ CREATE OR REPLACE PACKAGE BODY ins AS
-- dbms_output.put_line('today: '||to_char(today,'dd-mm-yyyy'));
-- Vandaag comprimeren mag niet want je weet niet of je alle meetwaarden al hebt.
end_day_compress := TRUNC(today);
end_day_compress := TRUNC(puntildate);
IF (end_day_compress = TRUNC(sysdate))
THEN
end_day_compress := end_day_compress -1;
END IF;
-- Voor welke dagen moet ins_deel_state_history gecomprimeerd worden?
-- (voor het geval ins_daily een aantal dagen niet heeft gewerkt.)
-- (voor het geval compress_states een aantal dagen niet heeft gewerkt.)
SELECT TRUNC(COALESCE(MIN(ins_deel_statedate), end_day_compress))
INTO first_day_available
FROM ins_deel_state_history;

View File

@@ -338,48 +338,191 @@ END;
/
CREATE_TRIGGER(ins_t_ins_deel_A_U)
AFTER UPDATE ON ins_deel
FOR EACH ROW
AFTER UPDATE
ON ins_deel
FOR EACH ROW
DECLARE
new_date DATE;
prev_state ins_deel_state_history.ins_deel_state%TYPE;
lmelder_oslogin CONSTANT VARCHAR (10) := '_HMAIL'; -- TODO!!!
new_date DATE;
prev_state ins_deel_state_history.ins_deel_state%TYPE;
lstate_history_key ins_deel_state_history.ins_deel_state_history_key%TYPE;
ins_srtdeel_statethreshold ins_srtdeel.ins_srtdeel_statethreshold%TYPE;
ldubbelcheck_key mld_melding.mld_melding_key%TYPE;
lstdmelding_key ins_srtdeel.mld_stdmelding_key%TYPE;
ldiscipline_key mld_stdmelding.mld_ins_discipline_key%TYPE;
lstatethreshold ins_srtdeel.ins_srtdeel_statethreshold%TYPE;
lmelding_key mld_melding.mld_melding_key%TYPE;
lmelder_key mld_melding.prs_perslid_key%TYPE;
BEGIN
IF (:old.ins_deel_state IS NULL AND :new.ins_deel_state IS NOT NULL)
OR (:new.ins_deel_state <> :old.ins_deel_state)
THEN
BEGIN
new_date := COALESCE (:new.ins_deel_statedate, SYSDATE); -- voorkom dat de update *net* een seconde later kan zijn
INSERT INTO ins_deel_state_history (ins_deel_key, ins_deel_state, ins_deel_statedate)
VALUES (:new.ins_deel_key, :new.ins_deel_state, COALESCE(:new.ins_deel_statedate, new_date));
EXCEPTION
WHEN DUP_VAL_ON_INDEX
THEN
BEGIN
SELECT ins_deel_state
INTO prev_state
FROM ins_deel_state_history
WHERE ins_deel_state_history_key =
(SELECT MAX (ins_deel_state_history_key)
FROM ins_deel_state_history
WHERE ins_deel_key = :new.ins_deel_key
AND ins_deel_statedate < new_date);
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
-- archiving chances in state_history
IF (:old.ins_deel_state IS NULL AND :new.ins_deel_state IS NOT NULL)
OR (:new.ins_deel_state <> :old.ins_deel_state)
THEN
BEGIN
new_date := COALESCE (:new.ins_deel_statedate, SYSDATE); -- voorkom dat de update *net* een seconde later kan zijn
IF (prev_state = :new.ins_deel_state)
INSERT INTO ins_deel_state_history (ins_deel_key, ins_deel_state, ins_deel_statedate)
VALUES (:new.ins_deel_key,
:new.ins_deel_state,
COALESCE (:new.ins_deel_statedate, new_date))
RETURNING ins_deel_state_history_key
INTO lstate_history_key;
EXCEPTION
WHEN DUP_VAL_ON_INDEX
THEN
DELETE ins_deel_state_history
WHERE ins_deel_key = :new.ins_deel_key
AND ins_deel_statedate = new_date;
ELSE -- kan alleen bij tri-stste statussen gebeuren
UPDATE ins_deel_state_history
SET ins_deel_state = :new.ins_deel_state
WHERE ins_deel_key = :new.ins_deel_key
AND ins_deel_statedate = new_date;
BEGIN
SELECT ins_deel_state
INTO prev_state
FROM ins_deel_state_history
WHERE ins_deel_state_history_key =
(SELECT MAX (ins_deel_state_history_key)
FROM ins_deel_state_history
WHERE ins_deel_key = :new.ins_deel_key
AND ins_deel_statedate < new_date);
EXCEPTION
WHEN NO_DATA_FOUND
THEN
NULL;
END;
IF (prev_state = :new.ins_deel_state)
THEN
DELETE ins_deel_state_history
WHERE ins_deel_key = :new.ins_deel_key AND ins_deel_statedate = new_date;
ELSE -- kan alleen bij tri-stste statussen gebeuren
UPDATE ins_deel_state_history
SET ins_deel_state = :new.ins_deel_state
WHERE ins_deel_key = :new.ins_deel_key AND ins_deel_statedate = new_date;
END IF;
END;
END IF;
-- potentially trigger dependent actions
IF (:old.ins_deel_state IS NULL AND :new.ins_deel_state IS NOT NULL)
OR (:new.ins_deel_state <> :old.ins_deel_state)
THEN
BEGIN
SELECT ins_srtdeel_statethreshold, mld_stdmelding_key
INTO lstatethreshold, lstdmelding_key
FROM ins_srtdeel
WHERE ins_srtdeel_key = :new.ins_srtdeel_key;
IF lstatethreshold IS NOT NULL
AND lstdmelding_key IS NOT NULL
AND ins.state_compare (:new.ins_deel_state, lstatethreshold) > 0
AND ins.state_compare (:old.ins_deel_state, lstatethreshold) <= 0
THEN
-- Eerst controleren of er niet al een "heel recente" melding bestaat
-- waarmee deze zou kunnen gaan overlappen. We hebben geen behoefte aan veel meer
-- meldingen over hetzelfde, wellicht zou het iets over de urgentie zeggen..
--
BEGIN
SELECT prs_perslid_key
INTO lmelder_key
FROM prs_perslid
WHERE prs_perslid_oslogin = lmelder_oslogin AND prs_perslid_verwijder IS NULL;
-- Ik denk dat het voorlopig voldoende is om te checken dat *wij* hier niet al eerder
-- een automatische melding hebben gegenereerd. Handmatige parallelle meldingen
-- beschouwen we niet. We willen primair voorkomen dat er in een paar minuten tientallen
-- meldingen ontstaan omdat de waarde rond de limiet flippert. Een daalmarge zou
-- een ander mechanisme hiertegen kunnen zijn, maar dit is intrinsieker.
-- Ik zoek de goedkoopst mogelijk check, ik weet hier al zeker dat we (weer)
-- de limiet overschrijden. We nemen de tijd niet in beschouwing, omdat voor de ene
-- toepassing 1 minuut recent is, en voor een andere misschien een maand.
SELECT m.mld_melding_key
INTO ldubbelcheck_key
FROM mld_melding m, mld_melding_object mo
WHERE m.mld_melding_key = mo.mld_melding_key
AND mo.ins_deel_key = :new.ins_deel_key
AND m.mld_stdmelding_key = lstdmelding_key
AND m.prs_perslid_key = lmelder_key
AND m.mld_melding_status IN (2,
0,
4,
7); -- lopend
IF ldubbelcheck_key IS NOT NULL -- puur voor de leesbaarheid, als er geen is gaan we nl in de exception verder
THEN
-- track this. This seems like an appropriate place.
UPDATE ins_deel_state_history
SET ins_deel_state_history_opmerk =
REPLACE (
REPLACE (lcl.l ('lcl_ins_sensorstate_already_mld'),
'{0}',
lmelding_key),
'{1}',
lstatethreshold)
WHERE ins_deel_state_history_key = lstate_history_key;
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
BEGIN
-- dit zou de trigger van mld_melding wel mogen doen..
SELECT msm.mld_ins_discipline_key
INTO ldiscipline_key
FROM mld_stdmelding msm
WHERE msm.mld_stdmelding_key = lstdmelding_key;
INSERT INTO mld_melding (mld_melding_module,
mld_meldbron_key,
mld_alg_locatie_key,
mld_alg_onroerendgoed_keys,
mld_melding_datum,
mld_melding_onderwerp,
mld_melding_omschrijving,
mld_stdmelding_key,
mld_melding_status,
mld_kosten_klant,
prs_perslid_key,
mld_melding_spoed,
mld_ins_discipline_key)
VALUES (
'MLD',
11, -- sensor
:new.ins_alg_locatie_key,
:new.ins_alg_ruimte_key,
SYSDATE,
lcl.l ('lcl_mld_state_generated_onderwerp'),
REPLACE (
REPLACE (
lcl.l ('lcl_mld_state_generated_omschrijving'),
'{0}',
:new.ins_deel_state),
'{1}',
lstatethreshold),
lstdmelding_key,
2, -- of afh mld_directklaar
NULL,
lmelder_key, --TODO!!!!!!! prs_perslid_key,
3,
ldiscipline_key)
RETURNING mld_melding_key
INTO lmelding_key;
--en het sensorobject erbij registreren
INSERT INTO mld_melding_object (ins_deel_key, mld_melding_key)
VALUES (:new.ins_deel_key, lmelding_key);
-- track this. This seems like an appropriate place.
UPDATE ins_deel_state_history
SET ins_deel_state_history_opmerk =
REPLACE (
REPLACE (lcl.l ('lcl_ins_sensorstate_caused_mld'),
'{0}',
lmelding_key),
'{1}',
lstatethreshold)
WHERE ins_deel_state_history_key = lstate_history_key;
-- If defined kick off the workflow
mld.mld_nextworkflowstep (lmelding_key, -1);
END;
END;
END IF;
END;
END IF;
END;
END IF;
END;
/