Ignore:
Timestamp:
09/11/14 17:23:54 (10 years ago)
Author:
frank.jaeger
Message:

Kleinere Korrekturen an den Import-Scripten.

File:
1 edited

Legend:

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

    r330 r331  
    1818 
    1919-- 2014-09-04  Trigger-Funktion "delete_feature_kill()" angepasst: keine Tabelle "alkis_beziehungen" mehr. 
     20 
     21-- 2014-09-11  Functions auskommentiert oder gelöscht, die "alkis_beziehungen" benötigen: 
     22--               "alkis_mviews()", delete_feature_kill_vers07(), alkis_beziehung_inserted() 
     23--             Trigger-Function "delete_feature_hist" durch aktuelle Version aus OSGeo4W ersetzt. 
    2024 
    2125-- Table/View/Sequence löschen, wenn vorhanden 
     
    162166 
    163167-- Übersicht erzeugen, die alle alkis_beziehungen mit den Typen der beteiligen ALKIS-Objekte versieht 
     168/* 
    164169SELECT alkis_dropobject('alkis_mviews'); 
    165170CREATE FUNCTION alkis_mviews() RETURNS varchar AS $$ 
     
    191196END; 
    192197$$ LANGUAGE plpgsql; 
     198*/ 
    193199 
    194200-- Indizes erzeugen 
     
    275281$$ LANGUAGE plpgsql; 
    276282 
     283-- Die folgende Trigger-Version kopiert aus  OSGeo4W / apps / alkis-import, Datei:alkis-functions.sql 
     284 
    277285-- Im Trigger 'delete_feature_trigger' muss eine dieser beiden Funktionen 
    278286-- (delete_feature_hist oder delete_feature_kill) verlinkt werden, je nachdem ob nur 
     
    280288 
    281289-- Löschsatz verarbeiten (MIT Historie) 
     290-- context='update'        => "endet" auf ÃŒbergebene Zeit setzen und anlass festhalten 
    282291-- context='delete'        => "endet" auf aktuelle Zeit setzen 
    283292-- context='replace'       => "endet" des ersetzten auf "beginnt" des neuen Objekts setzen 
    284293CREATE OR REPLACE FUNCTION delete_feature_hist() RETURNS TRIGGER AS $$ 
    285294DECLARE 
    286         sql TEXT; 
    287         gml_id TEXT; 
     295        s TEXT; 
     296        alt_id TEXT; 
     297        neu_id TEXT; 
     298        beginnt TEXT; 
    288299        endete TEXT; 
    289300        n INTEGER; 
    290301BEGIN 
    291302        NEW.context := lower(NEW.context); 
    292         gml_id      := substr(NEW.featureid, 1, 16); 
    293  
    294303        IF NEW.context IS NULL THEN 
    295304                NEW.context := 'delete'; 
     305        END IF; 
     306 
     307        -- TIMESTAMP weder in gml_id noch identifier verlÀßlich. 
     308        -- also ggf. aus Datenbank holen 
     309 
     310        IF length(NEW.featureid)=32 THEN 
     311                alt_id  := substr(NEW.featureid, 1, 16); 
     312 
     313                IF NEW.featureid<>NEW.replacedBy THEN 
     314                        -- Beginnt-Datum aus Timestamp 
     315                        beginnt := substr(NEW.featureid, 17, 4) || '-' 
     316                                || substr(NEW.featureid, 21, 2) || '-' 
     317                                || substr(NEW.featureid, 23, 2) || 'T' 
     318                                || substr(NEW.featureid, 26, 2) || ':' 
     319                                || substr(NEW.featureid, 28, 2) || ':' 
     320                                || substr(NEW.featureid, 30, 2) || 'Z' 
     321                                ; 
     322                END IF; 
     323        ELSIF length(NEW.featureid)=16 THEN 
     324                alt_id  := NEW.featureid; 
     325        ELSE 
     326                RAISE EXCEPTION '%: LÀnge 16 oder 32 statt % erwartet.', NEW.featureid, length(NEW.featureid); 
     327        END IF; 
     328 
     329        IF beginnt IS NULL THEN 
     330                -- Beginnt-Datum des Àltesten Eintrag, der nicht untergegangen ist 
     331                -- => der Satz dessen 'endet' gesetzt werden muß 
     332                EXECUTE 'SELECT min(beginnt) FROM ' || NEW.typename 
     333                        || ' WHERE gml_id=''' || alt_id || '''' 
     334                        || ' AND endet IS NULL' 
     335                        INTO beginnt; 
     336        END IF; 
     337 
     338        IF beginnt IS NULL THEN 
     339                IF NEW.context = 'delete' OR NEW.safetoignore = 'true' THEN 
     340                        RAISE NOTICE 'Kein Beginndatum fÃŒr Objekt % gefunden - ignoriert.', alt_id; 
     341                        NEW.ignored := true; 
     342                        RETURN NEW; 
     343                ELSE 
     344                        RAISE EXCEPTION 'Kein Beginndatum fÃŒr Objekt % gefunden.', alt_id; 
     345                END IF; 
    296346        END IF; 
    297347 
     
    308358                END IF; 
    309359 
    310                 IF NEW.replacedBy IS NULL OR length(NEW.replacedBy)<16 THEN 
    311                         IF NEW.safetoignore = 'true' THEN 
    312                                 RAISE NOTICE '%: Nachfolger ''%'' nicht richtig gesetzt - ignoriert', NEW.featureid, NEW.replacedBy; 
    313                                 NEW.ignored := true; 
    314                                 RETURN NEW; 
     360                IF length(NEW.replacedBy)=32 THEN 
     361                        -- Beginnt-Datum aus Timestamp 
     362                        IF NEW.featureid<>NEW.replacedBy THEN 
     363                                endete  := substr(NEW.replacedBy, 17, 4) || '-' 
     364                                        || substr(NEW.replacedBy, 21, 2) || '-' 
     365                                        || substr(NEW.replacedBy, 23, 2) || 'T' 
     366                                        || substr(NEW.replacedBy, 26, 2) || ':' 
     367                                        || substr(NEW.replacedBy, 28, 2) || ':' 
     368                                        || substr(NEW.replacedBy, 30, 2) || 'Z' 
     369                                        ; 
     370                        END IF; 
     371                ELSIF length(NEW.replacedBy)<>16 THEN 
     372                        RAISE EXCEPTION '%: LÀnge 16 oder 32 statt % erwartet.', NEW.replacedBy, length(NEW.replacedBy); 
     373                END IF; 
     374 
     375                neu_id := NEW.replacedBy; 
     376                IF endete IS NULL THEN 
     377                        -- Beginnt-Datum des neuesten Eintrag, der nicht untergegangen ist 
     378                        -- => Enddatum fÃŒr vorherigen Satz 
     379                        EXECUTE 'SELECT max(beginnt) FROM ' || NEW.typename 
     380                                || ' WHERE gml_id=''' || NEW.replacedBy || '''' 
     381                                || ' AND beginnt>''' || beginnt || '''' 
     382                                || ' AND endet IS NULL' 
     383                                INTO endete; 
     384                        IF endete IS NULL AND length(NEW.replacedBy)=32 THEN 
     385                                EXECUTE 'SELECT max(beginnt) FROM ' || NEW.typename 
     386                                        || ' WHERE gml_id=''' || substr(NEW.replacedBy, 1, 16) || '''' 
     387                                        || ' AND beginnt>''' || beginnt || '''' 
     388                                        || ' AND endet IS NULL' 
     389                                INTO endete; 
     390                                neu_id := substr(NEW.replacedBy, 1, 16); 
     391                        END IF; 
     392                END IF; 
     393 
     394                IF alt_id<>substr(neu_id, 1, 16) THEN 
     395                        RAISE NOTICE 'Objekt % wird durch Objekt % ersetzt.', alt_id, neu_id; 
     396                END IF; 
     397 
     398                IF endete IS NULL THEN 
     399                        RAISE NOTICE 'Kein Beginndatum fÃŒr Objekt % gefunden.', NEW.replacedBy; 
     400                END IF; 
     401 
     402                IF endete IS NULL OR beginnt=endete THEN 
     403                        RAISE EXCEPTION 'Objekt % wird durch Objekt % ersetzt (leere Lebensdauer?).', alt_id, neu_id; 
     404                END IF; 
     405        ELSIF NEW.context='update' THEN 
     406                endete := NEW.endet; 
     407        ELSE 
     408                RAISE EXCEPTION '%: UngÃŒltiger Kontext % (''delete'', ''replace'' oder ''update'' erwartet).', NEW.featureid, NEW.context; 
     409        END IF; 
     410 
     411        s   := 'UPDATE ' || NEW.typename 
     412            || ' SET endet=''' || endete || '''' 
     413            || ',anlass=''' || coalesce(NEW.anlass,'000000') || '''' 
     414            || ' WHERE gml_id=''' || NEW.featureid || '''' 
     415            || ' AND beginnt=''' || beginnt || '''' 
     416            || ' AND endet IS NULL'; 
     417        EXECUTE s; 
     418        GET DIAGNOSTICS n = ROW_COUNT; 
     419        IF n=0 AND alt_id<>NEW.featureid THEN 
     420                s   := 'UPDATE ' || NEW.typename 
     421                    || ' SET endet=''' || endete || '''' 
     422                    || ',anlass=''' || coalesce(NEW.anlass,'000000') || '''' 
     423                    || ' WHERE gml_id=''' || alt_id || '''' 
     424                    || ' AND beginnt=''' || beginnt || '''' 
     425                    || ' AND endet IS NULL'; 
     426                EXECUTE s; 
     427                GET DIAGNOSTICS n = ROW_COUNT; 
     428        END IF; 
     429 
     430        IF n<>1 THEN 
     431                RAISE NOTICE 'SQL[%<>1]: %', n, s; 
     432                IF NEW.context = 'delete' OR NEW.safetoignore = 'true' THEN 
     433                        RAISE NOTICE '%: Untergangsdatum von % Objekten statt einem auf % gesetzt - ignoriert', NEW.featureid, n, endete; 
     434                        NEW.ignored := true; 
     435                        RETURN NEW; 
     436                ELSIF n=0 THEN 
     437                        EXECUTE 'SELECT endet FROM ' || NEW.typename || 
     438                                ' WHERE gml_id=''' || alt_id || '''' || 
     439                                ' AND beginnt=''' || beginnt || '''' 
     440                                INTO endete; 
     441 
     442                        IF NOT endete IS NULL THEN 
     443                                RAISE NOTICE '%: Objekt bereits % untergegangen - ignoriert', NEW.featureid, endete; 
    315444                        ELSE 
    316                                 RAISE EXCEPTION '%: Nachfolger ''%'' nicht richtig gesetzt - Abbruch', NEW.featureid, NEW.replacedBy; 
     445                                RAISE NOTICE '%: Objekt nicht gefunden - ignoriert', NEW.featureid; 
    317446                        END IF; 
    318                 END IF; 
    319  
    320                 IF length(NEW.replacedBy)=16 THEN 
    321                         EXECUTE 'SELECT beginnt FROM ' || NEW.typename || 
    322                                 ' WHERE gml_id=''' || NEW.replacedBy || ''' AND endet IS NULL' || 
    323                                 ' ORDER BY beginnt DESC LIMIT 1' 
    324                            INTO endete; 
    325                 ELSE 
    326                         -- replaceBy mit Timestamp 
    327                         EXECUTE 'SELECT beginnt FROM ' || NEW.typename || 
    328                                 ' WHERE identifier=''urn:adv:oid:' || NEW.replacedBy || '''' 
    329                            INTO endete; 
    330                         IF endete IS NULL THEN 
    331                                 EXECUTE 'SELECT beginnt FROM ' || NEW.typename || 
    332                                         ' WHERE gml_id=''' || substr(NEW.replacedBy,1,16) || ''' AND endet IS NULL' || 
    333                                         ' ORDER BY beginnt DESC LIMIT 1' 
    334                                    INTO endete; 
    335                         END IF; 
    336                 END IF; 
    337  
    338                 IF endete IS NULL THEN 
    339                         IF NEW.safetoignore = 'true' THEN 
    340                                 RAISE NOTICE '%: Nachfolger % nicht gefunden - ignoriert', NEW.featureid, NEW.replacedBy; 
    341                                 NEW.ignored := true; 
    342                                 RETURN NEW; 
    343                         ELSE 
    344                                 RAISE EXCEPTION '%: Nachfolger % nicht gefunden', NEW.featureid, NEW.replacedBy; 
    345                         END IF; 
    346                 END IF; 
    347         ELSE 
    348                 RAISE EXCEPTION '%: UngÃŒltiger Kontext % (''delete'' oder ''replace'' erwartet).', NEW.featureid, NEW.context; 
    349         END IF; 
    350  
    351         sql     := 'UPDATE ' || NEW.typename 
    352                 || ' SET endet=''' || endete || '''' 
    353                 || ' WHERE gml_id=''' || gml_id || '''' 
    354                 || ' AND endet IS NULL' 
    355                 || ' AND beginnt<''' || endete || ''''; 
    356         -- RAISE NOTICE 'SQL: %', sql; 
    357         EXECUTE sql; 
    358         GET DIAGNOSTICS n = ROW_COUNT; 
    359         IF n<>1 THEN 
    360                 RAISE NOTICE 'SQL: %', sql; 
    361                 IF NEW.context = 'delete' OR NEW.safetoignore = 'true' THEN 
    362                         RAISE NOTICE '%: Untergangsdatum von % Objekten statt nur einem auf % gesetzt - ignoriert', NEW.featureid, n, endete; 
     447 
    363448                        NEW.ignored := true; 
    364449                        RETURN NEW; 
    365450                ELSE 
    366                         RAISE EXCEPTION '%: Untergangsdatum von % Objekten statt nur einem auf % gesetzt - Abbruch', NEW.featureid, n, endete; 
     451                        RAISE EXCEPTION '%: Untergangsdatum von % Objekten statt einem auf % gesetzt - Abbruch', NEW.featureid, n, endete; 
    367452                END IF; 
    368453        END IF; 
     
    373458$$ LANGUAGE plpgsql; 
    374459 
    375 -- "delete" und "replace" verarbeiten (OHNE Historie). Historische Objekte werden sofort gelöscht. 
    376 -- Geaendert 2014-02-03 auf Vorschlag M.B. Krs. Unna 
    377  
    378 -- 2014-08-27: Anpassung an vereinheitlichtes Datenbank-Schema. 
    379 -- Wenn die Spalte gml_id im Format "character varying" (ohne LÀngenbegrenzung) angelegt wird, 
    380 -- muss gezielt der ID-Teil vor dem Timestamp angesprochen werden. 
    381 -- Zugriff auf die Spalte gml_id umgestellt von "=" auf "like". 
    382 CREATE OR REPLACE FUNCTION delete_feature_kill_vers07() RETURNS TRIGGER AS $$ 
    383 DECLARE 
    384         begsql TEXT; 
    385         aktbeg TEXT; 
    386         gml_id TEXT; 
    387 BEGIN 
    388         NEW.typename := lower(NEW.typename); -- Objektart = Tabellen-Name 
    389         NEW.context := lower(NEW.context);   -- Operation 'delete', 'replace' oder 'update' 
    390         gml_id      := substr(NEW.featureid, 1, 16); -- ID-Teil der gml_id, ggf. anhÀngender Timestamp abgeschnitten 
    391  
    392         IF NEW.context IS NULL THEN 
    393                 NEW.context := 'delete'; -- default 
    394         END IF; 
    395  
    396         IF NEW.context='delete' THEN -- ersatzloses Löschen des Objektes 
    397  
    398           -- In der Objekt-Tabelle 
    399                 EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id like ''' || gml_id || '%'''; 
    400   
    401          -- Beziehungen von und zu dem Objekt sind hinfaellig (zukÃŒnftig entfallend) 
    402                 EXECUTE 'DELETE FROM alkis_beziehungen WHERE beziehung_von = ''' || gml_id || ''' OR beziehung_zu = ''' || gml_id || ''''; 
    403  
    404                 --RAISE NOTICE 'Lösche gml_id % in % und Beziehungen', gml_id, NEW.typename; 
    405  
    406         ELSE -- Ersetzen eines Objektes (Replace). In der Objekt-Tabelle sind jetzt bereits 2 Objekte vorhanden (alt und neu). 
    407  
    408                 -- beginnt-Wert des aktuellen Objektes ermitteln 
    409                 begsql := 'SELECT max(beginnt) FROM ' || NEW.typename || ' WHERE gml_id like ''' || substr(NEW.replacedBy, 1, 16) || '%'' AND endet IS NULL'; 
    410                 EXECUTE begsql INTO aktbeg; 
    411  
    412                 -- Alte Objekte entfernen 
    413                 EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id like ''' || gml_id || '%'' AND beginnt < ''' || aktbeg || ''''; 
    414  
    415                 -- Beziehungen des alten Objektes entfernen, die aus frÃŒheren Importen stammen 
    416                 EXECUTE 'DELETE FROM alkis_beziehungen WHERE beziehung_von like ''' || gml_id || '%'' AND import_id < (SELECT max(id) FROM import)'; 
    417  
    418         END IF; 
    419  
    420         NEW.ignored := false; 
    421         RETURN NEW; 
    422 END; 
    423 $$ LANGUAGE plpgsql; 
    424460 
    425461-- 2014-09-04: Version 0.8 ohne "alkis_beziehungen"-Tabelle 
     
    459495 
    460496-- BeziehungssÀtze aufrÀumen 
     497/* 
    461498CREATE OR REPLACE FUNCTION alkis_beziehung_inserted() RETURNS TRIGGER AS $$ 
    462499BEGIN 
     
    465502END; 
    466503$$ LANGUAGE plpgsql; 
     504*/ 
    467505 
    468506 
Note: See TracChangeset for help on using the changeset viewer.