Ignore:
Timestamp:
09/26/14 13:23:28 (10 years ago)
Author:
frank.jaeger
Message:

Neuer Trigger ohne Historie. Anzahl Kontext-Operationen in import-Tabelle eintragen.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/import/alkis-functions.sql

    r336 r338  
    3030--             mehrerer VorgÀnger- und Nachfolger-Objekte mit und ohne "endet IS NULL" geben. 
    3131 
     32-- 2014-09-23  FJ: Korrektur "delete_feature_kill()": 
     33--             Die neue Hist-Version vereinfachen (endet nicht benötigt) und zum Löschen umbauen. 
    3234 
    3335-- Table/View/Sequence löschen, wenn vorhanden 
     
    380382-- context='replace'       => "endet" des ersetzten auf "beginnt" des neuen Objekts setzen 
    381383-- context='update'        => "endet" auf ÃŒbergebene Zeit setzen und "anlass" festhalten 
     384-- Die "gml_id" muss in der Datenbank das Format character(16) haben. 
    382385CREATE OR REPLACE FUNCTION delete_feature_hist() RETURNS TRIGGER AS $$ 
    383386DECLARE 
     
    503506 
    504507 
    505 -- 2014-09-04: Version 0.8 ohne "alkis_beziehungen"-Tabelle 
     508-- Version PostNAS 0.8 ohne "alkis_beziehungen"-Tabelle 
    506509-- Unterschied von "delete_feature_kill" zur Version "delete_feature_hist": 
    507 --  Historisch gewordene Objekte werden nicht auf "endet" gesetzt sondern ganz aus der Datenbank gelöscht. 
    508 -- Achtung: Wenn diese Funktion mit dem "delete_feature_trigger" der Tabelle "delete" verknÃŒpft ist, 
    509 -- dann dÃŒrfen nur NAS-NBA-Daten verarbeitet werden, die mit der Abgabeart 1000 erzeugt wurden. 
    510 -- Wenn Daten der Abgabeart 3100 verarbeitet werden kommen update-Anweisungen in den Daten vor,  
    511 -- die dieser Trigger nicht verarbeiten kann. 
    512 CREATE OR REPLACE FUNCTION delete_feature_kill() RETURNS TRIGGER AS $$ 
     510--  Historisch gewordene Objekte werden nicht auf "endet" gesetzt sondern sofort aus der Datenbank gelöscht. 
     511 
     512-- Version von 2014-09-04 bis 2014-09-23 
     513-- Ohne Tabelle "alkis_beziehungen". 
     514-- Die gml_id kann in der Datenbenk das Format "character varying" haben (angehÀngte Beginn-Zeit). 
     515-- Diese Version kennt den NAS-Kontext "update" nicht und kann daher nur die Abgabeart 1000 verarbeiten. 
     516CREATE OR REPLACE FUNCTION delete_feature_kill_abg1000() RETURNS TRIGGER AS $$ 
    513517DECLARE 
    514518        begsql TEXT; 
     
    516520        gml_id TEXT; 
    517521BEGIN 
     522        -- Alte Version, die nur die Abgabeart 1000 (ohne replace) verarbeiten kann. 
    518523        NEW.typename := lower(NEW.typename); -- Objektart=Tabellen-Name 
    519524        NEW.context := lower(NEW.context);   -- Operation 'delete'/'replace'/'update' 
     
    524529        END IF; 
    525530        IF NEW.context='delete' THEN -- Löschen des Objektes 
    526           -- In der Objekt-Tabelle 
    527531                EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id like ''' || gml_id || '%'''; 
    528532                --RAISE NOTICE 'Lösche gml_id % in %', gml_id, NEW.typename; 
     
    530534 
    531535                -- beginnt-Wert des aktuellen Objektes ermitteln 
     536                -- besser ?   WHERE substring(gml_id,1,16) = ''' || gml_id || ''' 
    532537                begsql := 'SELECT max(beginnt) FROM ' || NEW.typename || ' WHERE gml_id like ''' || substr(NEW.replacedBy, 1, 16) || '%'' AND endet IS NULL'; 
    533538                EXECUTE begsql INTO aktbeg; 
     
    535540                -- Alte Objekte entfernen 
    536541                EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id like ''' || gml_id || '%'' AND beginnt < ''' || aktbeg || ''''; 
    537  
     542        END IF; 
     543 
     544        NEW.ignored := false; 
     545        RETURN NEW; 
     546END; 
     547$$ LANGUAGE plpgsql; 
     548 
     549 
     550-- Version ab 2014-09-23 (PostNAS 0.8) 
     551-- Abwandlung der Hist-Version als Kill-Version. 
     552-- Die "gml_id" muss in der Datenbank das Format character(16) haben. 
     553-- Dies kann auch Abgabeart 3100 verarbeiten. Historische Objekte werden aber sofort entfernt. 
     554CREATE OR REPLACE FUNCTION delete_feature_kill() RETURNS TRIGGER AS $$ 
     555DECLARE 
     556        n INTEGER; 
     557        vbeginnt TEXT; 
     558        replgml TEXT; 
     559        featgml TEXT; 
     560        s TEXT; 
     561BEGIN 
     562        -- Version 2014-09-23, replace fÃŒhrt auch zum Löschen des VorgÀngerobjektes 
     563        NEW.context := coalesce(lower(NEW.context),'delete'); 
     564 
     565        IF NEW.anlass IS NULL THEN 
     566                NEW.anlass := ''; 
     567        END IF; 
     568        featgml := substr(NEW.featureid, 1, 16); -- gml_id ohne Timestamp 
     569 
     570        IF length(NEW.featureid)=32 THEN 
     571                -- beginnt-Zeit der zu löschenden Vorgaenger-Version des Objektes 
     572                vbeginnt := substr(NEW.featureid, 17, 4) || '-' 
     573                        || substr(NEW.featureid, 21, 2) || '-' 
     574                        || substr(NEW.featureid, 23, 2) || 'T' 
     575                        || substr(NEW.featureid, 26, 2) || ':' 
     576                        || substr(NEW.featureid, 28, 2) || ':' 
     577                        || substr(NEW.featureid, 30, 2) || 'Z' ; 
     578        ELSIF length(NEW.featureid)=16 THEN 
     579                -- Ältestes nicht gelöschtes Objekt 
     580                EXECUTE 'SELECT min(beginnt) FROM ' || NEW.typename 
     581                        || ' WHERE gml_id=''' || featgml || '''' || ' AND endet IS NULL' 
     582                        INTO vbeginnt; 
     583 
     584                IF vbeginnt IS NULL THEN 
     585                        RAISE EXCEPTION '%: Keinen Kandidaten zum Löschen gefunden.', NEW.featureid; 
     586                END IF; 
     587        ELSE 
     588                RAISE EXCEPTION '%: Identifikator gescheitert.', NEW.featureid; 
     589        END IF; 
     590 
     591        IF NEW.context='delete' THEN 
     592        ELSIF NEW.context='update' THEN 
     593        ELSIF NEW.context='replace' THEN 
     594                NEW.safetoignore := lower(NEW.safetoignore); 
     595                IF NEW.safetoignore IS NULL THEN 
     596                        RAISE EXCEPTION '%: safeToIgnore nicht gesetzt.', NEW.featureid; 
     597                ELSIF NEW.safetoignore<>'true' AND NEW.safetoignore<>'false' THEN 
     598                        RAISE EXCEPTION '%: safeToIgnore ''%'' ungÃŒltig (''true'' oder ''false'' erwartet).', NEW.featureid, NEW.safetoignore; 
     599                END IF; 
     600        ELSE 
     601                RAISE EXCEPTION '%: UngÃŒltiger Kontext % (''delete'', ''replace'' oder ''update'' erwartet).', NEW.featureid, NEW.context; 
     602        END IF; 
     603 
     604        -- Vorgaenger ALKIS-Objekt Loeschen 
     605        s := 'DELETE FROM ' || NEW.typename || ' WHERE gml_id=''' || featgml || ''' AND beginnt=''' || vbeginnt || '''' ; 
     606        EXECUTE s; 
     607        GET DIAGNOSTICS n = ROW_COUNT; 
     608        -- RAISE NOTICE 'SQL[%]:%', n, s; 
     609        IF n<>1 THEN 
     610                RAISE EXCEPTION '%: % schlug fehl [%]', NEW.featureid, NEW.context, n; 
     611                -- dieser Satz kommt nicht in die delete-Tabelle? 
    538612        END IF; 
    539613 
     
    591665END; 
    592666$$ LANGUAGE plpgsql; 
     667 
     668 
     669-- 2014-09-22 Kopie aus Norbit-Github 
     670-- Funktioniert nicht wenn SchlÃŒsseltabellen mit "ax_" beginnen wie die Objekt-Tabellen. 
     671-- Darin wird dann z.B. die Splate "endet" gesucht. 
     672-- ToDo: besseres Namens-Schema fÃŒr Tabellen. 
     673--   z.B. Umbenennen "ax_buchungsstelle_buchungsart" -> "v_bs_buchungsart" 
     674CREATE OR REPLACE FUNCTION alkis_hist_check() RETURNS varchar AS $$ 
     675DECLARE 
     676        c RECORD; 
     677        n INTEGER; 
     678        r VARCHAR; 
     679BEGIN 
     680        FOR c IN SELECT table_name FROM information_schema.tables WHERE table_schema='public' AND substr(table_name,1,3) IN ('ax_','ap_','ks_') AND table_type='BASE TABLE' 
     681        LOOP 
     682                EXECUTE 'SELECT count(*) FROM ' || c.table_name || ' WHERE endet IS NULL GROUP BY gml_id HAVING count(*)>1' INTO n; 
     683                IF n>1 THEN 
     684                        r := coalesce(r||E'\n','') || c.table_name || ': ' || n || ' Objekte, die in mehreren Versionen nicht beendet sind.'; 
     685                END IF; 
     686 
     687                EXECUTE 'SELECT count(*) FROM ' || c.table_name || ' WHERE beginnt>=endet' INTO n; 
     688                IF n>1 THEN 
     689                        r := coalesce(r||E'\n','') || c.table_name || ': ' || n || ' Objekte mit ungÃŒltiger Lebensdauer.'; 
     690                END IF; 
     691 
     692                EXECUTE 'SELECT count(*)' 
     693                        || ' FROM ' || c.table_name || ' a' 
     694                        || ' JOIN ' || c.table_name || ' b ON a.gml_id=b.gml_id AND a.ogc_fid<>b.ogc_fid AND a.beginnt<b.endet AND a.endet>b.beginnt' 
     695                        INTO n; 
     696                IF n>0 THEN 
     697                        r := coalesce(r||E'\n','') || c.table_name || ': ' || n || ' LebensdauerÃŒberschneidungen.'; 
     698                END IF; 
     699        END LOOP; 
     700 
     701        RETURN r; 
     702END; 
     703$$ LANGUAGE plpgsql; 
     704 
     705-- Aufruf: SELECT alkis_hist_check(); 
     706 
Note: See TracChangeset for help on using the changeset viewer.