我真的需要你的帮助。我的情况如下: 我试图在表中插入地理空间数据,但有一些多边形未关闭并给出错误。当错误发生时,它会取消插入并且不插入任何行。我想实现一个程序,跳过有错误的行并插入正确的行。
我正在使用 db2 数据库。 这是我正在处理的最后一个代码:
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
最佳答案
解决此类问题的最佳方法可能是为自己创建一些 UDF 来包装导致错误的函数(或隐式转换)。例如。你可以用这个
/*
* 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
然后,如果将 ST_MULTIPOLYGON
的任何调用更改为 DB_MULTIPOLYGON
,如果多边形未闭合,您将得到 NULL
db2 -x "values ST_MultiPolygon ('multipolygon (( (3 3, 4 6, 5 3, 3 5) ))', 1)"
会给
SQL20571N An error occurred in a spatial routine: "GSE3421N
Polygon is not closed.". SQLSTATE=38H15
但是这个
db2 -x "values DB_MultiPolygon ('multipolygon (( (3 3, 4 6, 5 3, 3 5) ))', 1)"
将返回NULL
,然后您可以选择插入或使用WHERE
过滤掉它
关于sql - 如何跳过插入 db2 中的错误行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65815083/