Changeset 331 for trunk/import/alkis-functions.sql
- Timestamp:
- 09/11/14 17:23:54 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/import/alkis-functions.sql
r330 r331 18 18 19 19 -- 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. 20 24 21 25 -- Table/View/Sequence löschen, wenn vorhanden … … 162 166 163 167 -- Ãbersicht erzeugen, die alle alkis_beziehungen mit den Typen der beteiligen ALKIS-Objekte versieht 168 /* 164 169 SELECT alkis_dropobject('alkis_mviews'); 165 170 CREATE FUNCTION alkis_mviews() RETURNS varchar AS $$ … … 191 196 END; 192 197 $$ LANGUAGE plpgsql; 198 */ 193 199 194 200 -- Indizes erzeugen … … 275 281 $$ LANGUAGE plpgsql; 276 282 283 -- Die folgende Trigger-Version kopiert aus OSGeo4W / apps / alkis-import, Datei:alkis-functions.sql 284 277 285 -- Im Trigger 'delete_feature_trigger' muss eine dieser beiden Funktionen 278 286 -- (delete_feature_hist oder delete_feature_kill) verlinkt werden, je nachdem ob nur … … 280 288 281 289 -- Löschsatz verarbeiten (MIT Historie) 290 -- context='update' => "endet" auf ÃŒbergebene Zeit setzen und anlass festhalten 282 291 -- context='delete' => "endet" auf aktuelle Zeit setzen 283 292 -- context='replace' => "endet" des ersetzten auf "beginnt" des neuen Objekts setzen 284 293 CREATE OR REPLACE FUNCTION delete_feature_hist() RETURNS TRIGGER AS $$ 285 294 DECLARE 286 sql TEXT; 287 gml_id TEXT; 295 s TEXT; 296 alt_id TEXT; 297 neu_id TEXT; 298 beginnt TEXT; 288 299 endete TEXT; 289 300 n INTEGER; 290 301 BEGIN 291 302 NEW.context := lower(NEW.context); 292 gml_id := substr(NEW.featureid, 1, 16);293 294 303 IF NEW.context IS NULL THEN 295 304 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; 296 346 END IF; 297 347 … … 308 358 END IF; 309 359 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; 315 444 ELSE 316 RAISE EXCEPTION '%: Nachfolger ''%'' nicht richtig gesetzt - Abbruch', NEW.featureid, NEW.replacedBy;445 RAISE NOTICE '%: Objekt nicht gefunden - ignoriert', NEW.featureid; 317 446 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 363 448 NEW.ignored := true; 364 449 RETURN NEW; 365 450 ELSE 366 RAISE EXCEPTION '%: Untergangsdatum von % Objekten statt nureinem auf % gesetzt - Abbruch', NEW.featureid, n, endete;451 RAISE EXCEPTION '%: Untergangsdatum von % Objekten statt einem auf % gesetzt - Abbruch', NEW.featureid, n, endete; 367 452 END IF; 368 453 END IF; … … 373 458 $$ LANGUAGE plpgsql; 374 459 375 -- "delete" und "replace" verarbeiten (OHNE Historie). Historische Objekte werden sofort gelöscht.376 -- Geaendert 2014-02-03 auf Vorschlag M.B. Krs. Unna377 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 DECLARE384 begsql TEXT;385 aktbeg TEXT;386 gml_id TEXT;387 BEGIN388 NEW.typename := lower(NEW.typename); -- Objektart = Tabellen-Name389 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 abgeschnitten391 392 IF NEW.context IS NULL THEN393 NEW.context := 'delete'; -- default394 END IF;395 396 IF NEW.context='delete' THEN -- ersatzloses Löschen des Objektes397 398 -- In der Objekt-Tabelle399 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 ermitteln409 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 entfernen413 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 stammen416 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;424 460 425 461 -- 2014-09-04: Version 0.8 ohne "alkis_beziehungen"-Tabelle … … 459 495 460 496 -- BeziehungssÀtze aufrÀumen 497 /* 461 498 CREATE OR REPLACE FUNCTION alkis_beziehung_inserted() RETURNS TRIGGER AS $$ 462 499 BEGIN … … 465 502 END; 466 503 $$ LANGUAGE plpgsql; 504 */ 467 505 468 506
Note: See TracChangeset
for help on using the changeset viewer.