GLE-Postgis-BLPS: Unterschied zwischen den Versionen
Aus kvwmap
(Die Seite wurde neu angelegt: „ #!/bin/bash DOCKER='docker exec -i pgsql' PGHOST='-h pgsql' PGPORT='-p 5432' PGDATABASE='-d xxxxxx' PGUSER='-U xxxxxx' PGOPTIONS='-v ON_ERROR_STOP=ON'…“) |
|||
| Zeile 13: | Zeile 13: | ||
schema="xplan" | schema="xplan" | ||
| − | # 17000 = User-ID | + | # 17000 = User-ID von gisadmin |
OGR2OGR="docker exec --user 17000 -i gdal ogr2ogr" | OGR2OGR="docker exec --user 17000 -i gdal ogr2ogr" | ||
Aktuelle Version vom 23. Oktober 2023, 10:25 Uhr
#!/bin/bash
DOCKER='docker exec -i pgsql'
PGHOST='-h pgsql'
PGPORT='-p 5432'
PGDATABASE='-d xxxxxx'
PGUSER='-U xxxxxx'
PGOPTIONS='-v ON_ERROR_STOP=ON'
PSQL="${DOCKER} psql ${PGHOST} ${PGPORT} ${PGDATABASE} ${PGUSER} ${PGOPTIONS}"
pgConnection="PG:host='pgsql' port='5432' user='xxxxxx' dbname='xxxxxx' password='xxxxxx'"
schema="xplan"
# 17000 = User-ID von gisadmin
OGR2OGR="docker exec --user 17000 -i gdal ogr2ogr"
wfsURL="https://bauleitplaene-mv.de/dienste/basic?version=2.0.0&"
getFeature="service=WFS&request=GetFeature&srsname=EPSG:25833&typename="
featureTypes=("B_Plan" "F_Plan")
xplanURL="https://xleitstelle.de/downloads/xplanung/releases/"
xPlanV="${xplanURL}XPlanung Version 5.4/XPlanGML_5_4_Enumerationen_XML-Dictionary.XML"
blpMVURL="https://bauleitplaene-mv.de/codelist/"
################################################################################
############################## Schema-Definition ###############################
################################################################################
${PSQL} <<-SQL
SELECT to_regnamespace('${schema}') IS NULL AS createschema
\gset
\if :createschema
BEGIN;
CREATE SCHEMA "${schema}";
/*
* Data Type xplan:...
*/
CREATE TYPE "${schema}".xp_begruendungabschnitt AS (
schluessel text,
"text" text);
CREATE TYPE "${schema}".xp_gemeinde AS (
ags text,
rs text,
gemeindename text,
ortsteilname text);
CREATE TYPE "${schema}".xp_generattribut AS (
"name" text);
CREATE TYPE "${schema}".xp_plangeber AS (
"name" text,
kennziffer text);
CREATE TYPE "${schema}".xp_spezexternereferenz AS (
georefurl text,
art text,
referenzname text,
referenzurl text,
beschreibung text,
datum date,
typ text);
CREATE TYPE "${schema}".xp_textabschnitt AS (
schluessel text,
gesetzlichegrundlage text,
"text" text);
CREATE TYPE "${schema}".xp_verbundenerplan AS (
planname text,
rechtscharakter text,
nummer text,
verbundenerplan text);
CREATE TYPE "${schema}".xp_verfahrensmerkmal AS (
vermerk text,
datum date,
signatur text,
signiert bool);
/*
* Feature Type xplan:...
*/
CREATE TABLE "${schema}".bp_plan (
gml_id text NOT NULL,
"name" text NULL,
nummer text NULL,
planart text[] NULL,
sonstplanart text NULL,
gemeinde "${schema}".xp_gemeinde[] NULL,
rechtsstand text NULL,
verfahren text NULL,
externereferenz "${schema}".xp_spezexternereferenz[] NULL,
texte "${schema}".xp_textabschnitt[] NULL,
begruendungstexte "${schema}".xp_begruendungabschnitt[] NULL,
beschreibung text NULL,
kommentar text NULL,
plangeber "${schema}".xp_plangeber NULL,
planaufstellendegemeinde "${schema}".xp_gemeinde[] NULL,
internalid text NULL,
status text NULL,
aufstellungsbeschlussdatum date NULL,
technherstelldatum date NULL,
ausfertigungsdatum date NULL,
traegerbeteiligungsstartdatum date[] NULL,
traegerbeteiligungsenddatum date[] NULL,
auslegungsstartdatum date[] NULL,
auslegungsenddatum date[] NULL,
aenderungenbisdatum date NULL,
genehmigungsdatum date NULL,
inkrafttretensdatum date NULL,
rechtsverordnungsdatum date NULL,
satzungsbeschlussdatum date NULL,
veraenderungssperre bool NULL,
veraenderungssperredatum date NULL,
untergangsdatum date NULL,
erschliessungsvertrag bool NULL,
durchfuehrungsvertrag bool NULL,
staedtebaulichervertrag bool NULL,
gruenordnungsplan bool NULL,
erstellungsmassstab int NULL,
bezugshoehe numeric NULL,
hoehenbezug text NULL,
verfahrensmerkmale "${schema}".xp_verfahrensmerkmal[] NULL,
hatgenerattribut "${schema}".xp_generattribut[] NULL,
aendert "${schema}".xp_verbundenerplan[] NULL,
wurdegeaendertvon "${schema}".xp_verbundenerplan[] NULL,
raeumlichergeltungsbereich geometry(multipolygon, 25833) NOT NULL);
CREATE TABLE "${schema}".fp_plan (
gml_id text NOT NULL,
"name" text NULL,
nummer text NULL,
planart text NOT NULL,
sonstplanart text NULL,
gemeinde "${schema}".xp_gemeinde[] NOT NULL,
rechtsstand text NULL,
verfahren text NULL,
externereferenz "${schema}".xp_spezexternereferenz[] NULL,
texte "${schema}".xp_textabschnitt[] NULL,
begruendungstexte "${schema}".xp_begruendungabschnitt[] NULL,
beschreibung text NULL,
kommentar text NULL,
plangeber "${schema}".xp_plangeber NULL,
planaufstellendegemeinde "${schema}".xp_gemeinde[] NULL,
internalid text NULL,
status text NULL,
entwurfsbeschlussdatum date NULL,
aufstellungsbeschlussdatum date NULL,
technherstelldatum date NULL,
traegerbeteiligungsstartdatum date[] NULL,
traegerbeteiligungsenddatum date[] NULL,
auslegungsstartdatum date[] NULL,
auslegungsenddatum date[] NULL,
aenderungenbisdatum date NULL,
planbeschlussdatum date NULL,
genehmigungsdatum date NULL,
wirksamkeitsdatum date NULL,
untergangsdatum date NULL,
erstellungsmassstab int NULL,
bezugshoehe numeric NULL,
verfahrensmerkmale "${schema}".xp_verfahrensmerkmal[] NULL,
sachgebiet text NULL,
hatgenerattribut "${schema}".xp_generattribut[] NULL,
aendert "${schema}".xp_verbundenerplan[] NULL,
wurdegeaendertvon "${schema}".xp_verbundenerplan[] NULL,
raeumlichergeltungsbereich geometry(multipolygon, 25833) NOT NULL);
/*
* Enumerationen xplan:...
*/
SELECT format(
'CREATE TABLE %I.%I (wert text, beschreibung text, dokumentation text);',
'${schema}',
relname
)
FROM (
VALUES ('bp_planart'::text), ('bp_rechtsstand'), ('bp_verfahren'),
('fp_planart'), ('fp_rechtsstand'), ('fp_verfahren'),
('xp_externerefernztyp'), ('xp_rechtscharakterplanaenderung')
) AS v (relname)
\gexec
/*
* Enumerationen externe Codelisten
*/
SELECT format(
'CREATE TABLE %I.%I (wert text, beschreibung text);',
'${schema}',
relname
)
FROM (
VALUES ('bp_sonstplanart'::text),
('bp_status'),
-- ('fp_sonstplanart'),
('fp_status')
) AS v (relname)
\gexec
COMMIT;
\else
\q
\endif
SQL
################################################################################
###################### Download der Pläne und Codelisten #######################
################################################################################
${OGR2OGR} -f PostgreSQL \
"${pgConnection}" \
"WFS:${wfsURL}${getFeature}ms:B_Plan" \
-oo EXPOSE_GML_ID=NO \
-nln "${schema}.bp_plan_tmp" \
-lco UNLOGGED=ON \
-lco OVERWRITE=YES \
-lco GEOMETRY_NAME=wkb_geometry \
-lco SPATIAL_INDEX=GIST \
-forceNullable \
--config PG_USE_COPY YES \
--config OGR_TRUNCATE YES &
${OGR2OGR} -f PostgreSQL \
"${pgConnection}" \
"WFS:${wfsURL}${getFeature}ms:F_Plan" \
-oo EXPOSE_GML_ID=NO \
-nln "${schema}.fp_plan_tmp" \
-lco UNLOGGED=ON \
-lco OVERWRITE=YES \
-lco GEOMETRY_NAME=wkb_geometry \
-lco SPATIAL_INDEX=GIST \
-forceNullable \
--config PG_USE_COPY YES \
--config OGR_TRUNCATE YES &
wait
xplanDict=$(wget -q -O "-" "${xPlanV}" | tail -n +2)
bp_sonstplanartDict=$(wget -q -O "-" "${blpMVURL}BP_SonstPlanArt/BP_SonstPlanArt.xml" | tail -n +2)
bp_statusDict=$(wget -q -O "-" "${blpMVURL}BP_Status/BP_Status.xml" | tail -n +2)
#fp_sonstplanartDict=$(wget -q -O "-" "${blpMVURL}FP_SonstPlanArt/FP_SonstPlanArt.xml" | tail -n +2)
fp_statusDict=$(wget -q -O "-" "${blpMVURL}FP_Status/FP_Status.xml" | tail -n +2)
################################################################################
######################### Daten einlesen und bereinigen ########################
################################################################################
formString1=$( cat <<-SQL
INSERT INTO "${schema}".%I
SELECT split_part(xt.wert, ':', 2) AS wert,
xt.beschreibung,
trim(xt.dokumentation, E'\n') AS dokumentation
FROM xp_dictionary,
xmltable(
xmlnamespaces(
'http://www.opengis.net/gml/3.2' AS xmlns,
'http://www.w3.org/2001/XMLSchema-instance' AS xsi,
'http://www.opengis.net/gml/3.2' AS gml
),
'/xmlns:Dictionary/xmlns:dictionaryEntry/xmlns:DefinitionCollection[@gml:id="%s"]/xmlns:definitionMember'
PASSING d
COLUMNS wert text PATH 'xmlns:Definition/xmlns:identifier',
beschreibung text PATH 'xmlns:Definition/xmlns:name',
dokumentation text PATH 'xmlns:Definition/xmlns:description'
) xt;
SQL
)
formString2=$( cat <<-SQL
INSERT INTO "${schema}".%I
SELECT xt.*
FROM xmltable(
xmlnamespaces(
'http://www.opengis.net/gml/3.1.1' AS xmlns,
'http://www.opengis.net/gml/3.1.1' AS gml
),
'/xmlns:Dictionary/gml:DictionaryEntry'
PASSING xmlparse(document %L)
COLUMNS wert text PATH 'gml:Definition/gml:identifier',
beschreibung text PATH 'gml:Definition/gml:name'
) xt;
SQL
)
${PSQL} <<-SQL
BEGIN;
-- Tabellen leeren (außer die zuvor importierten)
SELECT 'TRUNCATE TABLE '
|| string_agg(format('%I.%I', '${schema}', relname), ', ')
|| ';'
FROM pg_catalog.pg_class
WHERE (relnamespace, relkind, relpersistence) = ('${schema}'::regnamespace, 'r', 'p')
\gexec
-- Indizes löschen (außer die zuvor importierten)
SELECT format('DROP INDEX IF EXISTS %I.%I', relnamespace::regnamespace, relname)
FROM pg_catalog.pg_class
WHERE (relnamespace, relkind, relpersistence) = ('${schema}'::regnamespace, 'i', 'p')
\gexec
-- Enumerations-Tabellen füllen
CREATE TEMP TABLE xp_dictionary AS
SELECT xmlparse(document \$\$${xplanDict}\$\$) AS d\;
SELECT format(\$\$${formString1}\$\$, relname, enumeration)
FROM (
VALUES ('bp_planart'::text, 'BP_PlanArt'::text),
('bp_rechtsstand', 'BP_Rechtsstand'),
('bp_verfahren', 'BP_Verfahren'),
('fp_planart', 'FP_PlanArt'),
('fp_rechtsstand', 'FP_Rechtsstand'),
('fp_verfahren', 'FP_Verfahren'),
('xp_externerefernztyp', 'XP_ExterneReferenzTyp'),
('xp_rechtscharakterplanaenderung', 'XP_RechtscharakterPlanaenderung')
) AS v (relname, enumeration)
\gexec
-- Codelisten-Tabellen füllen
SELECT format(\$\$${formString2}\$\$, relname, enumeration)
FROM (
VALUES ('bp_sonstplanart'::text, \$\$${bp_sonstplanartDict}\$\$::text),
('bp_status', \$\$${bp_statusDict}\$\$),
--('fp_sonstplanart'::text, \$\$${fp_sonstplanartDict}\$\$),
('fp_status', \$\$${fp_statusDict}\$\$)
) AS v (relname, enumeration)
\gexec
/*
* BP_Plan
*/
CREATE TEMP TABLE bp_plan_13073 AS
SELECT DISTINCT ON (a.gml_id)
a.*
FROM "${schema}".bp_plan_tmp a
JOIN alkis_eigen.pp_kreis AS b
ON ST_Intersects(b.wkb_geometry, a.wkb_geometry);
CREATE TEMP TABLE bp_verbundenerplan AS
SELECT DISTINCT ON (gml_id, verbundenerplan)
gml_id,
verbundenerplan,
rechtscharakter
FROM (
SELECT b.gml_id, j.verbundenerplan, j.rechtscharakter
FROM bp_plan_13073 b,
json_populate_recordset(NULL::"${schema}".xp_verbundenerplan, b.aendert::json) j
WHERE j.verbundenerplan IS NOT NULL AND j.rechtscharakter IS NOT NULL
UNION
SELECT j.verbundenerplan, b.gml_id, j.rechtscharakter
FROM bp_plan_13073 b,
json_populate_recordset(NULL::"${schema}".xp_verbundenerplan, b.wurdegeaendertvon::json) j
WHERE j.verbundenerplan IS NOT NULL AND j.rechtscharakter IS NOT NULL
) foo
ORDER BY 1, 2, 3;
-- Lösche Verweise auf nicht existierende Pläne
DELETE FROM bp_verbundenerplan v
WHERE NOT EXISTS (SELECT FROM bp_plan_13073 b
WHERE b.gml_id = v.gml_id);
-- Lösche Verweise auf nicht existierende Pläne
DELETE FROM bp_verbundenerplan v
WHERE NOT EXISTS (SELECT FROM bp_plan_13073 b
WHERE b.gml_id = v.verbundenerplan);
INSERT INTO "${schema}".bp_plan
SELECT gml_id,
name,
nummer,
planart::text[],
sonstplanart,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_gemeinde
FROM json_populate_recordset(NULL::"${schema}".xp_gemeinde, gemeinde::json) j
), '{}') AS gemeinde,
rechtsstand,
verfahren,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_spezexternereferenz
FROM json_populate_recordset(NULL::"${schema}".xp_spezexternereferenz, externereferenz::json) j
), '{}') AS externereferenz,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_textabschnitt
FROM json_populate_recordset(NULL::"${schema}".xp_textabschnitt, texte::json) j
), '{}') AS texte,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_begruendungabschnitt
FROM json_populate_recordset(NULL::"${schema}".xp_begruendungabschnitt, begruendungstexte::json) j
), '{}') AS begruendungstexte,
beschreibung,
kommentar,
json_populate_record(NULL::"${schema}".xp_plangeber, plangeber::json)::"${schema}".xp_plangeber AS plangeber,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_gemeinde
FROM json_populate_recordset(NULL::"${schema}".xp_gemeinde, planaufstellendegemeinde::json) j
), '{}') AS planaufstellendegemeinde,
internalid,
(status::json->>'id') AS status,
aufstellungsbeschlussdatum::date,
technherstelldatum::date,
ausfertigungsdatum::date,
traegerbeteiligungsstartdatum::date[],
traegerbeteiligungsenddatum::date[],
auslegungsstartdatum::date[],
auslegungsenddatum::date[],
aenderungenbisdatum::date,
genehmigungsdatum::date,
inkrafttretensdatum::date,
rechtsverordnungsdatum::date,
satzungsbeschlussdatum::date,
veraenderungssperre::bool,
veraenderungssperredatum::date,
untergangsdatum::date,
erschliessungsvertrag::bool,
durchfuehrungsvertrag::bool,
staedtebaulichervertrag::bool,
gruenordnungsplan::bool,
erstellungsmassstab::int,
bezugshoehe::numeric,
hoehenbezug::text,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_verfahrensmerkmal
FROM json_populate_recordset(NULL::"${schema}".xp_verfahrensmerkmal, verfahrensmerkmale::json) j
), '{}') AS verfahrensmerkmale,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_generattribut
FROM json_populate_recordset(NULL::"${schema}".xp_generattribut, hatgenerattribut::json) j
), '{}') AS hatgenerattribut,
nullif(ARRAY(
SELECT ROW(tp.name, v.rechtscharakter, tp.nummer, tp.gml_id)::"${schema}".xp_verbundenerplan
FROM bp_verbundenerplan v
JOIN bp_plan_13073 tp
ON tp.gml_id = v.verbundenerplan
WHERE v.gml_id = p.gml_id
), '{}') AS aendert,
nullif(ARRAY(
SELECT ROW(tp.name, v.rechtscharakter, tp.nummer, tp.gml_id)::"${schema}".xp_verbundenerplan
FROM bp_verbundenerplan v
JOIN bp_plan_13073 tp
ON tp.gml_id = v.gml_id
WHERE v.verbundenerplan = p.gml_id
), '{}') AS wurdegeaendertvon,
ST_Multi(wkb_geometry)::geometry('MultiPolygon', 25833) AS raeumlichergeltungsbereich
FROM bp_plan_13073 p
ORDER BY gml_id;
DROP TABLE "${schema}".bp_plan_tmp;
CREATE UNIQUE INDEX bp_plan_gml_id
ON "${schema}".bp_plan
USING btree (gml_id);
CREATE INDEX bp_plan_raeumlichergeltungsbereich
ON "${schema}".bp_plan
USING gist (raeumlichergeltungsbereich);
/*
* FP_Plan
*/
CREATE TEMP TABLE fp_plan_13073 AS
SELECT DISTINCT ON (a.gml_id)
a.*
FROM "${schema}".fp_plan_tmp a
JOIN alkis_eigen.pp_kreis AS b
ON ST_Intersects(b.wkb_geometry, a.wkb_geometry);
CREATE TEMP TABLE fp_verbundenerplan AS
SELECT DISTINCT ON (gml_id, verbundenerplan)
gml_id,
verbundenerplan,
rechtscharakter
FROM (
SELECT b.gml_id, j.verbundenerplan, j.rechtscharakter
FROM fp_plan_13073 b,
json_populate_recordset(NULL::"${schema}".xp_verbundenerplan, b.aendert::json) j
WHERE j.verbundenerplan IS NOT NULL AND j.rechtscharakter IS NOT NULL
UNION
SELECT j.verbundenerplan, b.gml_id, j.rechtscharakter
FROM fp_plan_13073 b,
json_populate_recordset(NULL::"${schema}".xp_verbundenerplan, b.wurdegeaendertvon::json) j
WHERE j.verbundenerplan IS NOT NULL AND j.rechtscharakter IS NOT NULL
) foo
ORDER BY 1, 2, 3;
-- Lösche Verweise auf nicht existierende Pläne
DELETE FROM fp_verbundenerplan v
WHERE NOT EXISTS (SELECT FROM fp_plan_13073 b
WHERE b.gml_id = v.gml_id);
-- Lösche Verweise auf nicht existierende Pläne
DELETE FROM fp_verbundenerplan v
WHERE NOT EXISTS (SELECT FROM fp_plan_13073 b
WHERE b.gml_id = v.verbundenerplan);
INSERT INTO "${schema}".fp_plan
SELECT gml_id,
name,
nummer,
planart::text,
sonstplanart,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_gemeinde
FROM json_populate_recordset(NULL::"${schema}".xp_gemeinde, gemeinde::json) j
), '{}') AS gemeinde,
rechtsstand,
verfahren,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_spezexternereferenz
FROM json_populate_recordset(NULL::"${schema}".xp_spezexternereferenz, externereferenz::json) j
), '{}') AS externereferenz,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_textabschnitt
FROM json_populate_recordset(NULL::"${schema}".xp_textabschnitt, texte::json) j
), '{}') AS texte,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_begruendungabschnitt
FROM json_populate_recordset(NULL::"${schema}".xp_begruendungabschnitt, begruendungstexte::json) j
), '{}') AS begruendungstexte,
beschreibung,
kommentar,
json_populate_record(NULL::"${schema}".xp_plangeber, plangeber::json)::"${schema}".xp_plangeber AS plangeber,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_gemeinde
FROM json_populate_recordset(NULL::"${schema}".xp_gemeinde, planaufstellendegemeinde::json) j
), '{}') AS planaufstellendegemeinde,
internalid,
(status::json->>'id') AS status,
entwurfsbeschlussdatum::date,
aufstellungsbeschlussdatum::date,
technherstelldatum::date,
traegerbeteiligungsstartdatum::date[],
traegerbeteiligungsenddatum::date[],
auslegungsstartdatum::date[],
auslegungsenddatum::date[],
aenderungenbisdatum::date,
planbeschlussdatum::date,
genehmigungsdatum::date,
wirksamkeitsdatum::date,
untergangsdatum::date,
erstellungsmassstab::int,
bezugshoehe::numeric,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_verfahrensmerkmal
FROM json_populate_recordset(NULL::"${schema}".xp_verfahrensmerkmal, verfahrensmerkmale::json) j
), '{}') AS verfahrensmerkmale,
sachgebiet,
nullif(ARRAY(
SELECT ROW(j.*)::"${schema}".xp_generattribut
FROM json_populate_recordset(NULL::"${schema}".xp_generattribut, hatgenerattribut::json) j
), '{}') AS hatgenerattribut,
nullif(ARRAY(
SELECT ROW(tp.name, v.rechtscharakter, tp.nummer, tp.gml_id)::"${schema}".xp_verbundenerplan
FROM fp_verbundenerplan v
JOIN fp_plan_13073 tp
ON tp.gml_id = v.verbundenerplan
WHERE v.gml_id = p.gml_id
), '{}') AS aendert,
nullif(ARRAY(
SELECT ROW(tp.name, v.rechtscharakter, tp.nummer, tp.gml_id)::"${schema}".xp_verbundenerplan
FROM fp_verbundenerplan v
JOIN fp_plan_13073 tp
ON tp.gml_id = v.gml_id
WHERE v.verbundenerplan = p.gml_id
), '{}') AS wurdegeaendertvon,
ST_Multi(wkb_geometry)::geometry('MultiPolygon', 25833) AS raeumlichergeltungsbereich
FROM fp_plan_13073 p
ORDER BY gml_id;
DROP TABLE "${schema}".fp_plan_tmp;
CREATE UNIQUE INDEX fp_plan_gml_id
ON "${schema}".fp_plan
USING btree (gml_id);
CREATE INDEX fp_plan_raeumlichergeltungsbereich
ON "${schema}".fp_plan
USING gist (raeumlichergeltungsbereich);
-- Tabellen analysieren
SELECT format('ANALYZE %I.%I', relnamespace::regnamespace, relname)
FROM pg_catalog.pg_class
WHERE (relnamespace, relkind) = ('${schema}'::regnamespace, 'r')
\gexec
COMMENT ON SCHEMA "${schema}" IS
\$\$Wird über ${0} gefüllt. Zuletzt am $(date +%d.%m.%Y)\$\$;
COMMIT;
SQL
echo $SECONDS
exit