简体   繁体   中英

How to skip error lines in an insert db2?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM