source: trunk/import/alkis-functions.sql @ 331

Revision 331, 19.9 KB checked in by frank.jaeger, 10 years ago (diff)

Kleinere Korrekturen an den Import-Scripten.

Line 
1-- alkis-functions.sql - Trigger-Funktionen fÃŒr die FortfÃŒhrung der
2--                       alkis_beziehungen aus EintrÀgen der delete-Tabelle
3
4-- 2013-07-10: Erweiterung zur Verarbeitung der Replace-SÀtze in ALKIS-Beziehungen
5
6-- 2013-12-10:  In der Function "update_fields_beziehungen" den Fall behandeln, dass ein Objekt einer
7--             neuen Beziehung in keiner Tabelle gefunden wird.
8--             Wenn ein einzelnes Objekt fehlt, soll dies keine Auswirkungen auf andere Objekte haben.
9--             FÃŒllen von "zu_typename" auskommentiert.
10
11-- 2014-01-31: Deaktivieren von "update_fields_beziehungen",
12--             statt dessen verwenden der "import_id" um alte Relationen zu identifizieren und zu löschen.
13
14-- 2014-08-27: Angleichung des Datenbank-Schema an die NorBIT-Version.
15--             Die Trigger-Function "delete_feature_kill()" arbeitet falsch, wenn "gml_id" als "character varying" angelegt ist.
16--             Das Format war bisher charachter(16).
17--             Zugriff auf die Spalte gml_id umgestellt von "=" auf "like" um den individuellen Timestamp zu ignorieren.
18
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.
24
25-- Table/View/Sequence löschen, wenn vorhanden
26CREATE OR REPLACE FUNCTION alkis_dropobject(t TEXT) RETURNS varchar AS $$
27DECLARE
28        c RECORD;
29        s varchar;
30        r varchar;
31        d varchar;
32        i integer;
33        tn varchar;
34BEGIN
35        r := '';
36        d := '';
37
38        -- drop objects
39        FOR c IN SELECT relkind,relname
40                FROM pg_class
41                JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid
42                WHERE pg_namespace.nspname='public' AND pg_class.relname=t
43                ORDER BY relkind
44        LOOP
45                IF c.relkind = 'v' THEN
46                        r := r || d || 'Sicht ' || c.relname || ' gelöscht.';
47                        EXECUTE 'DROP VIEW ' || c.relname || ' CASCADE';
48                ELSIF c.relkind = 'r' THEN
49                        r := r || d || 'Tabelle ' || c.relname || ' gelöscht.';
50                        EXECUTE 'DROP TABLE ' || c.relname || ' CASCADE';
51                ELSIF c.relkind = 'S' THEN
52                        r := r || d || 'Sequenz ' || c.relname || ' gelöscht.';
53                        EXECUTE 'DROP SEQUENCE ' || c.relname;
54                ELSIF c.relkind <> 'i' THEN
55                        r := r || d || 'Typ ' || c.table_type || '.' || c.table_name || ' unerwartet.';
56                END IF;
57                d := E'\n';
58        END LOOP;
59
60        FOR c IN SELECT indexname FROM pg_indexes WHERE schemaname='public' AND indexname=t
61        LOOP
62                r := r || d || 'Index ' || c.indexname || ' gelöscht.';
63                EXECUTE 'DROP INDEX ' || c.indexname;
64                d := E'\n';
65        END LOOP;
66
67        FOR c IN SELECT proname,proargtypes
68                FROM pg_proc
69                JOIN pg_namespace ON pg_proc.pronamespace=pg_namespace.oid
70                WHERE pg_namespace.nspname='public' AND pg_proc.proname=t
71        LOOP
72                r := r || d || 'Funktion ' || c.proname || ' gelöscht.';
73
74                s := 'DROP FUNCTION ' || c.proname || '(';
75                d := '';
76
77                FOR i IN array_lower(c.proargtypes,1)..array_upper(c.proargtypes,1) LOOP
78                        SELECT typname INTO tn FROM pg_type WHERE oid=c.proargtypes[i];
79                        s := s || d || tn;
80                        d := ',';
81                END LOOP;
82
83                s := s || ')';
84
85                EXECUTE s;
86
87                d := E'\n';
88        END LOOP;
89
90        FOR c IN SELECT relname,conname
91                FROM pg_constraint
92                JOIN pg_class ON pg_constraint.conrelid=pg_constraint.oid
93                JOIN pg_namespace ON pg_constraint.connamespace=pg_namespace.oid
94                WHERE pg_namespace.nspname='public' AND pg_constraint.conname=t
95        LOOP
96                r := r || d || 'Constraint ' || c.conname || ' von ' || c.relname || ' gelöscht.';
97                EXECUTE 'ALTER TABLE ' || c.relname || ' DROP CONSTRAINT ' || c.conname;
98                d := E'\n';
99        END LOOP;
100
101        RETURN r;
102END;
103$$ LANGUAGE plpgsql;
104
105-- Alle ALKIS-Tabellen löschen
106SELECT alkis_dropobject('alkis_drop');
107CREATE FUNCTION alkis_drop() RETURNS varchar AS $$
108DECLARE
109        c RECORD;
110        r VARCHAR;
111        d VARCHAR;
112BEGIN
113        r := '';
114        d := '';
115        -- drop tables & views
116        FOR c IN SELECT table_type,table_name FROM information_schema.tables WHERE table_schema='public' AND ( substr(table_name,1,3) IN ('ax_','ap_','ks_') OR table_name IN ('alkis_beziehungen','delete')) ORDER BY table_type DESC LOOP
117                IF c.table_type = 'VIEW' THEN
118                        r := r || d || 'Sicht ' || c.table_name || ' gelöscht.';
119                        EXECUTE 'DROP VIEW ' || c.table_name || ' CASCADE';
120                ELSIF c.table_type = 'BASE TABLE' THEN
121                        r := r || d || 'Tabelle ' || c.table_name || ' gelöscht.';
122                        EXECUTE 'DROP TABLE ' || c.table_name || ' CASCADE';
123                ELSE
124                        r := r || d || 'Typ ' || c.table_type || '.' || c.table_name || ' unerwartet.';
125                END IF;
126                d := E'\n';
127        END LOOP;
128
129        -- clean geometry_columns
130        DELETE FROM geometry_columns
131                WHERE f_table_schema='public'
132                AND ( substr(f_table_name,1,2) IN ('ax_','ap_','ks_')
133                 OR f_table_name IN ('alkis_beziehungen','delete') );
134
135        RETURN r;
136END;
137$$ LANGUAGE plpgsql;
138
139-- Alle ALKIS-Tabellen leeren
140SELECT alkis_dropobject('alkis_delete');
141CREATE FUNCTION alkis_delete() RETURNS varchar AS $$
142DECLARE
143        c RECORD;
144        r varchar;
145        d varchar;
146BEGIN
147        r := '';
148        d := '';
149
150        -- drop views
151        FOR c IN
152                SELECT table_name
153                FROM information_schema.tables
154                WHERE table_schema='public' AND table_type='BASE TABLE'
155                  AND ( substr(table_name,1,3) IN ('ax_','ap_','ks_')
156                        OR table_name IN ('alkis_beziehungen','delete') )
157        LOOP
158                r := r || d || c.table_name || ' wurde geleert.';
159                EXECUTE 'DELETE FROM '||c.table_name;
160                d := E'\n';
161        END LOOP;
162
163        RETURN r;
164END;
165$$ LANGUAGE plpgsql;
166
167-- Übersicht erzeugen, die alle alkis_beziehungen mit den Typen der beteiligen ALKIS-Objekte versieht
168/*
169SELECT alkis_dropobject('alkis_mviews');
170CREATE FUNCTION alkis_mviews() RETURNS varchar AS $$
171DECLARE
172        sql TEXT;
173        delim TEXT;
174        c RECORD;
175BEGIN
176        SELECT alkis_dropobject('vbeziehungen') INTO sql;
177        SELECT alkis_dropobject('vobjekte') INTO sql;
178
179        delim := '';
180        sql := 'CREATE VIEW vobjekte AS ';
181
182        FOR c IN SELECT table_name FROM information_schema.columns WHERE column_name='gml_id' AND substr(table_name,1,3) IN ('ax_','ap_','ks_') LOOP
183                sql := sql || delim || 'SELECT gml_id,beginnt,''' || c.table_name || ''' AS table_name FROM ' || c.table_name;
184                delim := ' UNION ';
185        END LOOP;
186
187        EXECUTE sql;
188
189        CREATE VIEW vbeziehungen AS
190                SELECT  beziehung_von,(SELECT table_name FROM vobjekte WHERE gml_id=beziehung_von) AS typ_von
191                        ,beziehungsart
192                        ,beziehung_zu,(SELECT table_name FROM vobjekte WHERE gml_id=beziehung_zu) AS typ_zu
193                FROM alkis_beziehungen;
194
195        RETURN 'ALKIS-Views erzeugt.';
196END;
197$$ LANGUAGE plpgsql;
198*/
199
200-- Indizes erzeugen
201SELECT alkis_dropobject('alkis_update_schema');
202CREATE FUNCTION alkis_update_schema() RETURNS varchar AS $$
203DECLARE
204        sql TEXT;
205        c RECORD;
206        i RECORD;
207        n INTEGER;
208BEGIN
209        -- Spalten in delete ergÀnzen
210        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='ignored';
211        IF n=0 THEN
212                ALTER TABLE "delete" ADD ignored BOOLEAN;
213        END IF;
214
215        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='context';
216        IF n=0 THEN
217                ALTER TABLE "delete" ADD context VARCHAR;
218        END IF;
219
220        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='safetoignore';
221        IF n=0 THEN
222                ALTER TABLE "delete" ADD safetoignore VARCHAR;
223        END IF;
224
225        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='replacedby';
226        IF n=0 THEN
227                ALTER TABLE "delete" ADD replacedBy VARCHAR;
228        END IF;
229
230        -- Spalte identifier ergÀnzen, wo sie fehlt
231        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
232                AND     EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='beginnt'    AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
233                AND NOT EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='identifier' AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
234        LOOP
235                EXECUTE 'ALTER TABLE ' || c.table_name || ' ADD identifier character(44)';
236        END LOOP;
237
238        -- Spalte endet ergÀnzen, wo sie fehlt
239        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
240                AND     EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='beginnt' AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
241                AND NOT EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='endet'   AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
242        LOOP
243                EXECUTE 'ALTER TABLE ' || c.table_name || ' ADD endet character(20) CHECK (endet>beginnt)';
244        END LOOP;
245
246        -- Lebensdauer-Constraint ergÀnzen
247        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
248                AND EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='beginnt' AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
249                AND EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='endet'   AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
250        LOOP
251                SELECT alkis_dropobject(c.table_name||'_lebensdauer');
252                EXECUTE 'ALTER TABLE ' || c.table_name || ' ADD CONSTRAINT ' || c.table_name || '_lebensdauer CHECK (beginnt IS NOT NULL AND endet>beginnt)';
253        END LOOP;
254
255        -- Indizes aktualisieren
256        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
257                AND EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='beginnt' AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
258        LOOP
259                -- Vorhandene Indizes droppen (TODO: Löscht auch die SonderfÀlle - entfernen)
260                FOR i IN EXECUTE 'SELECT indexname FROM pg_indexes WHERE NOT indexname LIKE ''%_pk'' AND schemaname=''public'' AND tablename='''||c.table_name||'''' LOOP
261                        EXECUTE 'DROP INDEX ' || i.indexname;
262                END LOOP;
263
264                -- Indizes erzeugen
265                EXECUTE 'CREATE UNIQUE INDEX ' || c.table_name || '_id ON ' || c.table_name || '(gml_id,beginnt)';
266                EXECUTE 'CREATE UNIQUE INDEX ' || c.table_name || '_ident ON ' || c.table_name || '(identifier)';
267                EXECUTE 'CREATE INDEX ' || c.table_name || '_gmlid ON ' || c.table_name || '(gml_id)';
268                EXECUTE 'CREATE INDEX ' || c.table_name || '_beginnt ON ' || c.table_name || '(beginnt)';
269                EXECUTE 'CREATE INDEX ' || c.table_name || '_endet ON ' || c.table_name || '(endet)';
270        END LOOP;
271
272        -- Geometrieindizes aktualisieren
273        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
274                AND EXISTS (SELECT * FROM information_schema.columns b WHERE b.column_name='wkb_geometry' AND a.table_catalog=b.table_catalog AND a.table_schema=b.table_schema AND a.table_name=b.table_name)
275        LOOP
276                EXECUTE 'CREATE INDEX ' || c.table_name || '_geom ON ' || c.table_name || ' USING GIST (wkb_geometry)';
277        END LOOP;
278
279        RETURN 'Schema aktualisiert.';
280END;
281$$ LANGUAGE plpgsql;
282
283-- Die folgende Trigger-Version kopiert aus  OSGeo4W / apps / alkis-import, Datei:alkis-functions.sql
284
285-- Im Trigger 'delete_feature_trigger' muss eine dieser beiden Funktionen
286-- (delete_feature_hist oder delete_feature_kill) verlinkt werden, je nachdem ob nur
287-- aktuelle oder auch historische Objekte in der Datenbank gefÃŒhrt werden sollen.
288
289-- Löschsatz verarbeiten (MIT Historie)
290-- context='update'        => "endet" auf ÃŒbergebene Zeit setzen und anlass festhalten
291-- context='delete'        => "endet" auf aktuelle Zeit setzen
292-- context='replace'       => "endet" des ersetzten auf "beginnt" des neuen Objekts setzen
293CREATE OR REPLACE FUNCTION delete_feature_hist() RETURNS TRIGGER AS $$
294DECLARE
295        s TEXT;
296        alt_id TEXT;
297        neu_id TEXT;
298        beginnt TEXT;
299        endete TEXT;
300        n INTEGER;
301BEGIN
302        NEW.context := lower(NEW.context);
303        IF NEW.context IS NULL THEN
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;
346        END IF;
347
348        IF NEW.context='delete' THEN
349                endete := to_char(CURRENT_TIMESTAMP AT TIME ZONE 'UTC','YYYY-MM-DD"T"HH24:MI:SS"Z"');
350
351        ELSIF NEW.context='replace' THEN
352                NEW.safetoignore := lower(NEW.safetoignore);
353
354                IF NEW.safetoignore IS NULL THEN
355                        RAISE EXCEPTION '%: safeToIgnore nicht gesetzt.', NEW.featureid;
356                ELSIF NEW.safetoignore<>'true' AND NEW.safetoignore<>'false' THEN
357                        RAISE EXCEPTION '%: safeToIgnore ''%'' ungÃŒltig (''true'' oder ''false'' erwartet).', NEW.featureid, NEW.safetoignore;
358                END IF;
359
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;
444                        ELSE
445                                RAISE NOTICE '%: Objekt nicht gefunden - ignoriert', NEW.featureid;
446                        END IF;
447
448                        NEW.ignored := true;
449                        RETURN NEW;
450                ELSE
451                        RAISE EXCEPTION '%: Untergangsdatum von % Objekten statt einem auf % gesetzt - Abbruch', NEW.featureid, n, endete;
452                END IF;
453        END IF;
454
455        NEW.ignored := false;
456        RETURN NEW;
457END;
458$$ LANGUAGE plpgsql;
459
460
461-- 2014-09-04: Version 0.8 ohne "alkis_beziehungen"-Tabelle
462CREATE OR REPLACE FUNCTION delete_feature_kill() RETURNS TRIGGER AS $$
463DECLARE
464        begsql TEXT;
465        aktbeg TEXT;
466        gml_id TEXT;
467BEGIN
468        NEW.typename := lower(NEW.typename); -- Objektart=Tabellen-Name
469        NEW.context := lower(NEW.context);   -- Operation 'delete'/'replace'/'update'
470        gml_id      := substr(NEW.featureid, 1, 16); -- ID-Teil der gml_id, ohne Timestamp
471
472        IF NEW.context IS NULL THEN
473                NEW.context := 'delete'; -- default
474        END IF;
475        IF NEW.context='delete' THEN -- Löschen des Objektes
476          -- In der Objekt-Tabelle
477                EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id like ''' || gml_id || '%''';
478                --RAISE NOTICE 'Lösche gml_id % in %', gml_id, NEW.typename;
479        ELSE -- Ersetzen des Objektes (Replace). In der Objekt-Tabelle sind jetzt bereits 2 Objekte vorhanden (alt und neu).
480
481                -- beginnt-Wert des aktuellen Objektes ermitteln
482                begsql := 'SELECT max(beginnt) FROM ' || NEW.typename || ' WHERE gml_id like ''' || substr(NEW.replacedBy, 1, 16) || '%'' AND endet IS NULL';
483                EXECUTE begsql INTO aktbeg;
484
485                -- Alte Objekte entfernen
486                EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id like ''' || gml_id || '%'' AND beginnt < ''' || aktbeg || '''';
487
488        END IF;
489
490        NEW.ignored := false;
491        RETURN NEW;
492END;
493$$ LANGUAGE plpgsql;
494
495
496-- BeziehungssÀtze aufrÀumen
497/*
498CREATE OR REPLACE FUNCTION alkis_beziehung_inserted() RETURNS TRIGGER AS $$
499BEGIN
500        DELETE FROM alkis_beziehungen WHERE ogc_fid<NEW.ogc_fid AND beziehung_von=NEW.beziehung_von AND beziehungsart=NEW.beziehungsart AND beziehung_zu=NEW.beziehung_zu;
501        RETURN NEW;
502END;
503$$ LANGUAGE plpgsql;
504*/
505
506
507-- Wenn die Datenbank MIT Historie angelegt wurde, kann nach dem Laden hiermit aufgerÀumt werden.
508CREATE OR REPLACE FUNCTION alkis_delete_all_endet() RETURNS void AS $$
509DECLARE
510        c RECORD;
511BEGIN
512        -- In allen Tabellen die Objekte löschen, die ein Ende-Datum haben
513        FOR c IN
514                SELECT table_name
515                 FROM information_schema.columns a
516                WHERE a.column_name='endet'
517            AND a.is_updatable='YES' -- keine Views, die endet-Spalte haben
518                ORDER BY table_name
519        LOOP
520                EXECUTE 'DELETE FROM ' || c.table_name || ' WHERE NOT endet IS NULL';
521                -- RAISE NOTICE 'Lösche ''endet'' in: %', c.table_name;
522        END LOOP;
523END;
524$$ LANGUAGE plpgsql;
525
526
527-- Wenn die Datenbank ohne Historie gefÃŒhrt wird, ist das Feld "identifier" verzichtbar.
528-- Diese wird nur von der Trigger-Version fÃŒr die Version MIT Historie verwendet.
529-- Es kann aus allen Tabellen entfernt werden.
530CREATE OR REPLACE FUNCTION alkis_drop_all_identifier() RETURNS void AS $$
531DECLARE
532        c RECORD;
533BEGIN
534        FOR c IN
535                SELECT table_name
536                FROM information_schema.columns a
537                WHERE a.column_name='identifier'
538                ORDER BY table_name
539        LOOP
540                EXECUTE 'ALTER TABLE ' || c.table_name || ' DROP COLUMN identifier';
541                RAISE NOTICE 'Entferne ''identifier'' aus: %', c.table_name;
542        END LOOP;
543END;
544$$ LANGUAGE plpgsql;
545
546
547-- Funktion zum Ermitteln der letzten import_id
548CREATE OR REPLACE FUNCTION get_import_id() RETURNS TRIGGER AS $$
549BEGIN
550        EXECUTE 'SELECT max(id) FROM import' INTO NEW.import_id;
551        RETURN NEW;
552END;
553$$ LANGUAGE plpgsql;
Note: See TracBrowser for help on using the repository browser.