I really need your help. My case is as follows: I am trying to insert geo-spatial data in a table, but there are some multipolygons that are not closed and give an error. When the error happens it cancels the insert and does not insert any lines. I would like to implement a procedure that skips the lines with error and insert those that are correct.
I am working with the db2 database. Here is the last code I'm working on:
CREATE OR REPLACE PROCEDURE DDM.GEOMETRY_TESTE ()
LANGUAGE SQL
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '38SSL';
DECLARE CONTINUE HANDLER FOR SQLSTATE '38SSP';
BEGIN
CONTINUE;
END;
INSERT INTO ddm.DM_SICAR_GEOMETRY_TESTE (IDGEOSIGAM, ID_ORIGEM, TIPO_AREA, TIPO_COORDENADA, AREA_GEO, COORDENADAS, CENTROIDE, COORDENADAS_WKT, TESTE)
SELECT
b.IDGEOSIGAM
,b.ID_ORIGEM
,b.TIPO_AREA
,b.TIPO_COORDENADA
,b.AREA_GEO
,db2gse.ST_Point(CONCAT('point(',SUBSTRING(COORDENADAS2,1,LENGTH(b.COORDENADAS2)-2)||')'),1) COORDENADAS
,db2gse.ST_centroid(db2gse.ST_Point(CONCAT('point(',SUBSTRING(b.COORDENADAS2,1,LENGTH(b.COORDENADAS2)-2)||')'),1)) CENTROIDE
,CASE
WHEN b.TIPO_COORDENADA = 'Point' THEN CONCAT('POINT(',SUBSTRING(COORDENADAS2,1,LENGTH(COORDENADAS2)-2)||')')
WHEN b.TIPO_COORDENADA = 'MultiPolygon' THEN CONCAT('MULTIPOLYGON(((',SUBSTRING(COORDENADAS2,1,LENGTH(COORDENADAS2)-2)||')))')
END COORDENADAS_WKT
,CASE
WHEN b.TIPO_COORDENADA = 'Point' THEN db2gse.ST_Point(CONCAT('POINT(',SUBSTRING(b.COORDENADAS2,1,LENGTH(b.COORDENADAS2)-2)||')'),1)
WHEN b.TIPO_COORDENADA = 'MultiPolygon' THEN db2gse.ST_MultiPolygon(CONCAT('MULTIPOLYGON(((',SUBSTRING(b.COORDENADAS2,1,LENGTH(b.COORDENADAS2)-2)||')))'),1)
END TESTE
FROM
(
SELECT
a.IDGEOSIGAM
,a.ID_ORIGEM
,a.TIPO_AREA
,a.TIPO_COORDENADA
,a.AREA_GEO
,SUBSTRING(xmlserialize(xmlagg(xmltext(a.LONGLATI) ORDER BY a.ID_ORIGEM, a.IDGEOSIGAM, a.ID_SEQ) as CLOB(1073741824)), 0) COORDENADAS2
FROM
(
SELECT
g.IDGEOSIGAM
,g.ID_ORIGEM
,g.TIPO_AREA
,c.TIPO_COORDENADA
,g.AREA_GEO
,c.ID_SEQ
,c.LONGITUDE
,c.LATITUDE
,CONCAT(c.LATITUDE||' '||c.LONGITUDE,', ') LONGLATI
FROM
ddm.DM_SICAR_GEO g
INNER JOIN ddm.DM_SICAR_GEO_COORDENADAS c ON c.ID_ORIGEM = g.ID_ORIGEM AND c.IDGEOSIGAM = g.IDGEOSIGAM
WHERE
g.IDGEOSIGAM in (3274, 49069, 63397, 20224, 20222)
--g.ID_ORIGEM = 478
ORDER BY
g.ID_ORIGEM
,g.IDGEOSIGAM
,c.ID_SEQ
) a
GROUP BY
a.IDGEOSIGAM
,a.ID_ORIGEM
,a.TIPO_AREA
,a.TIPO_COORDENADA
,a.AREA_GEO
) b;
END
Probably the best way to cater for this kind of issue is to create yourself some UDFs that wrap the functions (or implicit casts) that are causing the error. Eg you could use this
/*
* Runs ST_MULTIPOLYGON but will return NULL if the function errors out with GSE3421N Polygon is not closed."
*/
CREATE OR REPLACE FUNCTION DB_MULTIPOLYGON(i CLOB(2G), srs_id INT DEFAULT 4326)
RETURNS db2gse.ST_MULTIPOLYGON
NO EXTERNAL ACTION
DETERMINISTIC
BEGIN
DECLARE NOT_VALID CONDITION FOR SQLSTATE '38H15';
DECLARE EXIT HANDLER FOR NOT_VALID RETURN NULL;
--
RETURN db2gse.ST_MULTIPOLYGON(I, SRS_ID );
END
Then if you change any call of ST_MULTIPOLYGON
to DB_MULTIPOLYGON
you will get a NULL back if the polygon is not closed
db2 -x "values ST_MultiPolygon ('multipolygon (( (3 3, 4 6, 5 3, 3 5) ))', 1)"
will give
SQL20571N An error occurred in a spatial routine: "GSE3421N
Polygon is not closed.". SQLSTATE=38H15
but this
db2 -x "values DB_MultiPolygon ('multipolygon (( (3 3, 4 6, 5 3, 3 5) ))', 1)"
will return NULL
which you can then either choose to insert, or filter out with a WHERE
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.