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

Revision 314, 17.3 KB checked in by frank.jaeger, 10 years ago (diff)

Trigger ohne Historie (kill) umgestellt auf Import-ID als Merkmal fuer Replace

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
15-- Table/View/Sequence löschen, wenn vorhanden
16CREATE OR REPLACE FUNCTION alkis_dropobject(t TEXT) RETURNS varchar AS $$
17DECLARE
18        c RECORD;
19        s varchar;
20        r varchar;
21        d varchar;
22        i integer;
23        tn varchar;
24BEGIN
25        r := '';
26        d := '';
27
28        -- drop objects
29        FOR c IN SELECT relkind,relname
30                FROM pg_class
31                JOIN pg_namespace ON pg_class.relnamespace=pg_namespace.oid
32                WHERE pg_namespace.nspname='public' AND pg_class.relname=t
33                ORDER BY relkind
34        LOOP
35                IF c.relkind = 'v' THEN
36                        r := r || d || 'Sicht ' || c.relname || ' gelöscht.';
37                        EXECUTE 'DROP VIEW ' || c.relname || ' CASCADE';
38                ELSIF c.relkind = 'r' THEN
39                        r := r || d || 'Tabelle ' || c.relname || ' gelöscht.';
40                        EXECUTE 'DROP TABLE ' || c.relname || ' CASCADE';
41                ELSIF c.relkind = 'S' THEN
42                        r := r || d || 'Sequenz ' || c.relname || ' gelöscht.';
43                        EXECUTE 'DROP SEQUENCE ' || c.relname;
44                ELSIF c.relkind <> 'i' THEN
45                        r := r || d || 'Typ ' || c.table_type || '.' || c.table_name || ' unerwartet.';
46                END IF;
47                d := E'\n';
48        END LOOP;
49
50        FOR c IN SELECT indexname FROM pg_indexes WHERE schemaname='public' AND indexname=t
51        LOOP
52                r := r || d || 'Index ' || c.indexname || ' gelöscht.';
53                EXECUTE 'DROP INDEX ' || c.indexname;
54                d := E'\n';
55        END LOOP;
56
57        FOR c IN SELECT proname,proargtypes
58                FROM pg_proc
59                JOIN pg_namespace ON pg_proc.pronamespace=pg_namespace.oid
60                WHERE pg_namespace.nspname='public' AND pg_proc.proname=t
61        LOOP
62                r := r || d || 'Funktion ' || c.proname || ' gelöscht.';
63
64                s := 'DROP FUNCTION ' || c.proname || '(';
65                d := '';
66
67                FOR i IN array_lower(c.proargtypes,1)..array_upper(c.proargtypes,1) LOOP
68                        SELECT typname INTO tn FROM pg_type WHERE oid=c.proargtypes[i];
69                        s := s || d || tn;
70                        d := ',';
71                END LOOP;
72
73                s := s || ')';
74
75                EXECUTE s;
76
77                d := E'\n';
78        END LOOP;
79
80        FOR c IN SELECT relname,conname
81                FROM pg_constraint
82                JOIN pg_class ON pg_constraint.conrelid=pg_constraint.oid
83                JOIN pg_namespace ON pg_constraint.connamespace=pg_namespace.oid
84                WHERE pg_namespace.nspname='public' AND pg_constraint.conname=t
85        LOOP
86                r := r || d || 'Constraint ' || c.conname || ' von ' || c.relname || ' gelöscht.';
87                EXECUTE 'ALTER TABLE ' || c.relname || ' DROP CONSTRAINT ' || c.conname;
88                d := E'\n';
89        END LOOP;
90
91        RETURN r;
92END;
93$$ LANGUAGE plpgsql;
94
95-- Alle ALKIS-Tabellen löschen
96SELECT alkis_dropobject('alkis_drop');
97CREATE FUNCTION alkis_drop() RETURNS varchar AS $$
98DECLARE
99        c RECORD;
100        r VARCHAR;
101        d VARCHAR;
102BEGIN
103        r := '';
104        d := '';
105        -- drop tables & views
106        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
107                IF c.table_type = 'VIEW' THEN
108                        r := r || d || 'Sicht ' || c.table_name || ' gelöscht.';
109                        EXECUTE 'DROP VIEW ' || c.table_name || ' CASCADE';
110                ELSIF c.table_type = 'BASE TABLE' THEN
111                        r := r || d || 'Tabelle ' || c.table_name || ' gelöscht.';
112                        EXECUTE 'DROP TABLE ' || c.table_name || ' CASCADE';
113                ELSE
114                        r := r || d || 'Typ ' || c.table_type || '.' || c.table_name || ' unerwartet.';
115                END IF;
116                d := E'\n';
117        END LOOP;
118
119        -- clean geometry_columns
120        DELETE FROM geometry_columns
121                WHERE f_table_schema='public'
122                AND ( substr(f_table_name,1,2) IN ('ax_','ap_','ks_')
123                 OR f_table_name IN ('alkis_beziehungen','delete') );
124
125        RETURN r;
126END;
127$$ LANGUAGE plpgsql;
128
129-- Alle ALKIS-Tabellen leeren
130SELECT alkis_dropobject('alkis_delete');
131CREATE FUNCTION alkis_delete() RETURNS varchar AS $$
132DECLARE
133        c RECORD;
134        r varchar;
135        d varchar;
136BEGIN
137        r := '';
138        d := '';
139
140        -- drop views
141        FOR c IN
142                SELECT table_name
143                FROM information_schema.tables
144                WHERE table_schema='public' AND table_type='BASE TABLE'
145                  AND ( substr(table_name,1,3) IN ('ax_','ap_','ks_')
146                        OR table_name IN ('alkis_beziehungen','delete') )
147        LOOP
148                r := r || d || c.table_name || ' wurde geleert.';
149                EXECUTE 'DELETE FROM '||c.table_name;
150                d := E'\n';
151        END LOOP;
152
153        RETURN r;
154END;
155$$ LANGUAGE plpgsql;
156
157-- Übersicht erzeugen, die alle alkis_beziehungen mit den Typen der beteiligen ALKIS-Objekte versieht
158SELECT alkis_dropobject('alkis_mviews');
159CREATE FUNCTION alkis_mviews() RETURNS varchar AS $$
160DECLARE
161        sql TEXT;
162        delim TEXT;
163        c RECORD;
164BEGIN
165        SELECT alkis_dropobject('vbeziehungen') INTO sql;
166        SELECT alkis_dropobject('vobjekte') INTO sql;
167
168        delim := '';
169        sql := 'CREATE VIEW vobjekte AS ';
170
171        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
172                sql := sql || delim || 'SELECT gml_id,beginnt,''' || c.table_name || ''' AS table_name FROM ' || c.table_name;
173                delim := ' UNION ';
174        END LOOP;
175
176        EXECUTE sql;
177
178--      CREATE UNIQUE INDEX vobjekte_gmlid ON vobjekte(gml_id,beginnt);
179--      CREATE INDEX vobjekte_table ON vobjekte(table_name);
180
181        CREATE VIEW vbeziehungen AS
182                SELECT  beziehung_von,(SELECT table_name FROM vobjekte WHERE gml_id=beziehung_von) AS typ_von
183                        ,beziehungsart
184                        ,beziehung_zu,(SELECT table_name FROM vobjekte WHERE gml_id=beziehung_zu) AS typ_zu
185                FROM alkis_beziehungen;
186
187--      CREATE INDEX vbeziehungen_von    ON vbeziehungen(beziehung_von);
188--      CREATE INDEX vbeziehungen_vontyp ON vbeziehungen(typ_von);
189--      CREATE INDEX vbeziehungen_art    ON vbeziehungen(beziehungsart);
190--      CREATE INDEX vbeziehungen_zu     ON vbeziehungen(beziehung_zu);
191--      CREATE INDEX vbeziehungen_zutyp  ON vbeziehungen(typ_zu);
192
193        RETURN 'ALKIS-Views erzeugt.';
194END;
195$$ LANGUAGE plpgsql;
196
197-- Indizes erzeugen
198SELECT alkis_dropobject('alkis_update_schema');
199CREATE FUNCTION alkis_update_schema() RETURNS varchar AS $$
200DECLARE
201        sql TEXT;
202        c RECORD;
203        i RECORD;
204        n INTEGER;
205BEGIN
206        -- Spalten in delete ergÀnzen
207        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='ignored';
208        IF n=0 THEN
209                ALTER TABLE "delete" ADD ignored BOOLEAN;
210        END IF;
211
212        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='context';
213        IF n=0 THEN
214                ALTER TABLE "delete" ADD context VARCHAR;
215        END IF;
216
217        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='safetoignore';
218        IF n=0 THEN
219                ALTER TABLE "delete" ADD safetoignore VARCHAR;
220        END IF;
221
222        SELECT count(*) INTO n FROM information_schema.columns WHERE table_schema='public' AND table_name='delete' AND column_name='replacedby';
223        IF n=0 THEN
224                ALTER TABLE "delete" ADD replacedBy VARCHAR;
225        END IF;
226
227        -- Spalte identifier ergÀnzen, wo sie fehlt
228        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
229                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)
230                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)
231        LOOP
232                EXECUTE 'ALTER TABLE ' || c.table_name || ' ADD identifier character(44)';
233        END LOOP;
234
235        -- Spalte endet ergÀnzen, wo sie fehlt
236        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
237                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)
238                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)
239        LOOP
240                EXECUTE 'ALTER TABLE ' || c.table_name || ' ADD endet character(20) CHECK (endet>beginnt)';
241        END LOOP;
242
243        -- Lebensdauer-Constraint ergÀnzen
244        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
245                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)
246                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)
247        LOOP
248                SELECT alkis_dropobject(c.table_name||'_lebensdauer');
249                EXECUTE 'ALTER TABLE ' || c.table_name || ' ADD CONSTRAINT ' || c.table_name || '_lebensdauer CHECK (beginnt IS NOT NULL AND endet>beginnt)';
250        END LOOP;
251
252        -- Indizes aktualisieren
253        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
254                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)
255        LOOP
256                -- Vorhandene Indizes droppen (TODO: Löscht auch die SonderfÀlle - entfernen)
257                FOR i IN EXECUTE 'SELECT indexname FROM pg_indexes WHERE NOT indexname LIKE ''%_pk'' AND schemaname=''public'' AND tablename='''||c.table_name||'''' LOOP
258                        EXECUTE 'DROP INDEX ' || i.indexname;
259                END LOOP;
260
261                -- Indizes erzeugen
262                EXECUTE 'CREATE UNIQUE INDEX ' || c.table_name || '_id ON ' || c.table_name || '(gml_id,beginnt)';
263                EXECUTE 'CREATE UNIQUE INDEX ' || c.table_name || '_ident ON ' || c.table_name || '(identifier)';
264                EXECUTE 'CREATE INDEX ' || c.table_name || '_gmlid ON ' || c.table_name || '(gml_id)';
265                EXECUTE 'CREATE INDEX ' || c.table_name || '_beginnt ON ' || c.table_name || '(beginnt)';
266                EXECUTE 'CREATE INDEX ' || c.table_name || '_endet ON ' || c.table_name || '(endet)';
267        END LOOP;
268
269        -- Geometrieindizes aktualisieren
270        FOR c IN SELECT table_name FROM information_schema.columns a WHERE a.column_name='gml_id'
271                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)
272        LOOP
273                EXECUTE 'CREATE INDEX ' || c.table_name || '_geom ON ' || c.table_name || ' USING GIST (wkb_geometry)';
274        END LOOP;
275
276        RETURN 'Schema aktualisiert.';
277END;
278$$ LANGUAGE plpgsql;
279
280-- Im Trigger 'delete_feature_trigger' muss eine dieser beiden Funktionen
281-- (delete_feature_hist oder delete_feature_kill) verlinkt werden, je nachdem ob nur
282-- aktuelle oder auch historische Objekte in der Datenbank gefÃŒhrt werden sollen.
283
284-- Löschsatz verarbeiten (MIT Historie)
285-- context='delete'        => "endet" auf aktuelle Zeit setzen
286-- context='replace'       => "endet" des ersetzten auf "beginnt" des neuen Objekts setzen
287CREATE OR REPLACE FUNCTION delete_feature_hist() RETURNS TRIGGER AS $$
288DECLARE
289        sql TEXT;
290        gml_id TEXT;
291        endete TEXT;
292        n INTEGER;
293BEGIN
294        NEW.context := lower(NEW.context);
295        gml_id      := substr(NEW.featureid, 1, 16);
296
297        IF NEW.context IS NULL THEN
298                NEW.context := 'delete';
299        END IF;
300
301        IF NEW.context='delete' THEN
302                endete := to_char(CURRENT_TIMESTAMP AT TIME ZONE 'UTC','YYYY-MM-DD"T"HH24:MI:SS"Z"');
303
304        ELSIF NEW.context='replace' THEN
305                NEW.safetoignore := lower(NEW.safetoignore);
306
307                IF NEW.safetoignore IS NULL THEN
308                        RAISE EXCEPTION '%: safeToIgnore nicht gesetzt.', NEW.featureid;
309                ELSIF NEW.safetoignore<>'true' AND NEW.safetoignore<>'false' THEN
310                        RAISE EXCEPTION '%: safeToIgnore ''%'' ungÃŒltig (''true'' oder ''false'' erwartet).', NEW.featureid, NEW.safetoignore;
311                END IF;
312
313                IF NEW.replacedBy IS NULL OR length(NEW.replacedBy)<16 THEN
314                        IF NEW.safetoignore = 'true' THEN
315                                RAISE NOTICE '%: Nachfolger ''%'' nicht richtig gesetzt - ignoriert', NEW.featureid, NEW.replacedBy;
316                                NEW.ignored := true;
317                                RETURN NEW;
318                        ELSE
319                                RAISE EXCEPTION '%: Nachfolger ''%'' nicht richtig gesetzt - Abbruch', NEW.featureid, NEW.replacedBy;
320                        END IF;
321                END IF;
322
323                IF length(NEW.replacedBy)=16 THEN
324                        EXECUTE 'SELECT beginnt FROM ' || NEW.typename ||
325                                ' WHERE gml_id=''' || NEW.replacedBy || ''' AND endet IS NULL' ||
326                                ' ORDER BY beginnt DESC LIMIT 1'
327                           INTO endete;
328                ELSE
329                        -- replaceBy mit Timestamp
330                        EXECUTE 'SELECT beginnt FROM ' || NEW.typename ||
331                                ' WHERE identifier=''urn:adv:oid:' || NEW.replacedBy || ''''
332                           INTO endete;
333                        IF endete IS NULL THEN
334                                EXECUTE 'SELECT beginnt FROM ' || NEW.typename ||
335                                        ' WHERE gml_id=''' || substr(NEW.replacedBy,1,16) || ''' AND endet IS NULL' ||
336                                        ' ORDER BY beginnt DESC LIMIT 1'
337                                   INTO endete;
338                        END IF;
339                END IF;
340
341                IF endete IS NULL THEN
342                        IF NEW.safetoignore = 'true' THEN
343                                RAISE NOTICE '%: Nachfolger % nicht gefunden - ignoriert', NEW.featureid, NEW.replacedBy;
344                                NEW.ignored := true;
345                                RETURN NEW;
346                        ELSE
347                                RAISE EXCEPTION '%: Nachfolger % nicht gefunden', NEW.featureid, NEW.replacedBy;
348                        END IF;
349                END IF;
350        ELSE
351                RAISE EXCEPTION '%: UngÃŒltiger Kontext % (''delete'' oder ''replace'' erwartet).', NEW.featureid, NEW.context;
352        END IF;
353
354        sql     := 'UPDATE ' || NEW.typename
355                || ' SET endet=''' || endete || ''''
356                || ' WHERE gml_id=''' || gml_id || ''''
357                || ' AND endet IS NULL'
358                || ' AND beginnt<''' || endete || '''';
359        -- RAISE NOTICE 'SQL: %', sql;
360        EXECUTE sql;
361        GET DIAGNOSTICS n = ROW_COUNT;
362        IF n<>1 THEN
363                RAISE NOTICE 'SQL: %', sql;
364                IF NEW.context = 'delete' OR NEW.safetoignore = 'true' THEN
365                        RAISE NOTICE '%: Untergangsdatum von % Objekten statt nur einem auf % gesetzt - ignoriert', NEW.featureid, n, endete;
366                        NEW.ignored := true;
367                        RETURN NEW;
368                ELSE
369                        RAISE EXCEPTION '%: Untergangsdatum von % Objekten statt nur einem auf % gesetzt - Abbruch', NEW.featureid, n, endete;
370                END IF;
371        END IF;
372
373        NEW.ignored := false;
374        RETURN NEW;
375END;
376$$ LANGUAGE plpgsql;
377
378
379-- "delete" und "replace" verarbeiten (OHNE Historie). Historische Objekte werden sofort gelöscht.
380-- Geaendert 2014-02-03 auf Vorschlag M.B. Krs. Unna
381CREATE OR REPLACE FUNCTION delete_feature_kill() RETURNS TRIGGER AS $$
382DECLARE
383        query TEXT;
384        begsql TEXT;
385        aktbeg TEXT;
386        gml_id TEXT;
387        query_bez TEXT;
388BEGIN
389        NEW.typename := lower(NEW.typename);
390        NEW.context := lower(NEW.context);
391        gml_id      := substr(NEW.featureid, 1, 16);
392
393        IF NEW.context IS NULL THEN
394                NEW.context := 'delete';
395        END IF;
396
397        IF NEW.context='delete' THEN -- Ersatzloses Loeschen des Objektes
398          -- In der Objekt-Tabelle
399                EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id = ''' || gml_id || '''';
400          -- Beziehungen von und zu dem Objekt sind hinfaellig
401                EXECUTE 'DELETE FROM alkis_beziehungen WHERE beziehung_von = ''' || gml_id || ''' OR beziehung_zu = ''' || gml_id || '''';
402                --RAISE NOTICE 'Lösche gml_id % in % und Beziehungen', gml_id, NEW.typename;
403
404        ELSE -- Ersetzen eines Objektes (Replace). In der Objekt-Tabelle sind jetzt bereits 2 Objekte vorhanden (alt und neu).
405                -- beginnt-Wert des aktuellen Objektes ermitteln
406                begsql := 'SELECT max(beginnt) FROM ' || NEW.typename || ' WHERE gml_id = ''' || substr(NEW.replacedBy, 1, 16) || ''' AND endet IS NULL';
407                EXECUTE begsql INTO aktbeg;
408                -- Alte Objekte entfernen
409                EXECUTE 'DELETE FROM ' || NEW.typename || ' WHERE gml_id = ''' || gml_id || ''' AND beginnt < ''' || aktbeg || '''';
410                -- Beziehungen vom alten Objekt entfernen, die aus frueheren Importen stammen
411                EXECUTE 'DELETE FROM alkis_beziehungen WHERE beziehung_von = ''' || gml_id || ''' AND import_id < (SELECT max(id) FROM import)';
412        END IF;
413
414        NEW.ignored := false;
415        RETURN NEW;
416END;
417$$ LANGUAGE plpgsql;
418
419
420-- BeziehungssÀtze aufrÀumen
421CREATE OR REPLACE FUNCTION alkis_beziehung_inserted() RETURNS TRIGGER AS $$
422BEGIN
423        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;
424        RETURN NEW;
425END;
426$$ LANGUAGE plpgsql;
427
428
429-- Wenn die Datenbank MIT Historie angelegt wurde, kann nach dem Laden hiermit aufgerÀumt werden.
430CREATE OR REPLACE FUNCTION alkis_delete_all_endet() RETURNS void AS $$
431DECLARE
432        c RECORD;
433BEGIN
434        -- In allen Tabellen die Objekte löschen, die ein Ende-Datum haben
435        FOR c IN
436                SELECT table_name
437                FROM information_schema.columns a
438                WHERE a.column_name='endet'
439                ORDER BY table_name
440        LOOP
441                EXECUTE 'DELETE FROM ' || c.table_name || ' WHERE NOT endet IS NULL';
442                -- RAISE NOTICE 'Lösche ''endet'' in: %', c.table_name;
443        END LOOP;
444END;
445$$ LANGUAGE plpgsql;
446
447
448-- Wenn die Datenbank ohne Historie gefÃŒhrt wird, ist das Feld "identifier" verzichtbar.
449-- Diese wird nur von der Trigger-Version fÃŒr die Version MIT Historie verwendet.
450-- Es kann aus allen Tabellen entfernt werden.
451CREATE OR REPLACE FUNCTION alkis_drop_all_identifier() RETURNS void AS $$
452DECLARE
453        c RECORD;
454BEGIN
455        FOR c IN
456                SELECT table_name
457                FROM information_schema.columns a
458                WHERE a.column_name='identifier'
459                ORDER BY table_name
460        LOOP
461                EXECUTE 'ALTER TABLE ' || c.table_name || ' DROP COLUMN identifier';
462                RAISE NOTICE 'Entferne ''identifier'' aus: %', c.table_name;
463        END LOOP;
464END;
465$$ LANGUAGE plpgsql;
466
467
468-- Funktion zum Ermitteln der letzten import_id
469CREATE OR REPLACE FUNCTION get_import_id() RETURNS TRIGGER AS $$
470BEGIN
471        EXECUTE 'SELECT max(id) FROM import' INTO NEW.import_id;
472        RETURN NEW;
473END;
474$$ LANGUAGE plpgsql;
Note: See TracBrowser for help on using the repository browser.