Oracle sdo_geomery 자료를 PostgreSQL + PostGIS 기반으로 옮겨가기

이글은 이전 홈페이지에서 2012년 쓰다만 글입니다.
그래도 남겨 놓아야겠기에.
이젠 많이 바뀌어서 아래 글이 바르지 않을 수도 있습니다.
오라클 sdo_geometry 자료형에 대해서는
페이지를
sdo_geometry 자료형을 PostgreSQL 자료형으로 변환 하는 원문은
페이지를
PostGIS 관련 문서는
페이지들을 참조로 작성될 것입니다.
Oracle sdo_geometry 자료형 구조
PostgreSQL용 오라클 호환 sdo_geometry
먼저 위에서 언급한 대로 일단 똑같은 mdsys.sdo_geometry 자료형을 하나 만든다.
CREATE DOMAIN mdsys.sdo_elem_info_array AS numeric[]; CREATE DOMAIN mdsys.sdo_ordinate_array AS numeric[]; CREATE TYPE mdsys.sdo_point_type AS (x numeric, y numeric, z numeric); CREATE TYPE mdsys.sdo_geometry AS ( sdo_gtype numeric, sdo_srid numeric, sdo_point mdsys.sdo_point_type, sdo_elem_info mdsys.sdo_elem_info_array, sdo_ordinates mdsys.sdo_ordinate_array);
이 자료형은 PostgreSQL 표준 복합 자료형이 됨으로, 입출력 또한 그대로 하면 된다.
dblink를 이용한 자료 옮기기
먼저 오라클에서 sdo_geometry 자료를 PostgreSQL 입력 포멧으로 바꾸기 위해서, 위에서 언급한 사이트에서 제공한 패키지를 약간 수정해서 만든다.
CREATE OR REPLACE PACKAGE pg_user_geom_util AS -- copyright (c) 2012, Nicander Ltd -- url: http://www.tolon.co.uk/2012/09/geometry-objects-across-dblink/ -- modified by ioseph -- Translates a geometry object into a string representation -- for storage and transport. See also StringToGeom. FUNCTION GeomToString(pGeom IN mdsys.sdo_geometry ) RETURN VARCHAR2 DETERMINISTIC; END pg_user_geom_util; CREATE OR REPLACE PACKAGE BODY ADMCHOI.pg_user_geom_util AS -- copyright (c) 2012, Nicander Ltd -- url: http://www.tolon.co.uk/2012/09/geometry-objects-across-dblink/ -- modified by ioseph -- Gets the next token in a separated list. See StringToGeom for an example. PROCEDURE get_token( iStart IN NUMBER, sPattern in VARCHAR2, sBuffer in VARCHAR2, sResult OUT NOCOPY VARCHAR2, iNextPos OUT NOCOPY NUMBER ) IS nPos1 number; nPos2 number; BEGIN nPos1 := Instr(sBuffer, sPattern, iStart); IF nPos1 = 0 then sResult := rtrim(ltrim(substr(sBuffer, iStart, LENGTH(sBuffer) - iStart))); ELSE sResult := Rtrim(Ltrim(Substr(sBuffer, iStart, nPos1 - iStart))); iNextPos := nPos1 + 1; END IF; END; -------------------------------------------------------------------------------- FUNCTION NumberToString(pNumber IN NUMBER) RETURN VARCHAR2 IS BEGIN IF (pNumber IS NULL) THEN RETURN ''; ELSE RETURN TO_CHAR(pNumber); END IF; EXCEPTION WHEN OTHERS THEN RETURN ''; END; function emptytonull(pString in varchar2) return varchar2 is begin return case when pString = '' then 'null' else pString end; end; -------------------------------------------------------------------------------- FUNCTION StringToNumber(pString IN VARCHAR2) RETURN NUMBER IS BEGIN RETURN TO_NUMBER(pString); EXCEPTION WHEN OTHERS THEN RETURN NULL; END; -------------------------------------------------------------------------------- -- String format is as follows: -- --, , , , -- -- Where: -- := -- := -- := NULL | SDO_POINT_TYPE, OPTIONAL_NUMBER, OPTIONAL_NUMBER, OPTIONAL_NUMBER -- := NULL | SDO_ELEM_INFO_ARRAY, NUMBER, {OPTIONAL_NUMBER, ...} -- := NULL | SDO_ORDINATE_ARRAY, NUMBER, {OPTIONAL_NUMBER, ...} -- -- := NULL | NUMBER -- entries in curly braces are repeated from n times FUNCTION GeomToString(pGeom IN mdsys.sdo_geometry ) RETURN VARCHAR2 DETERMINISTIC IS vString VARCHAR(32767); vCount NUMBER; BEGIN -- GTYPE vString := NumberToString(pGeom.SDO_GTYPE); -- SRID vString := vString || ',' || NumberToString(pGeom.SDO_SRID); -- POINT IF (pGeom.SDO_POINT IS NULL) THEN vString := vString || ','; ELSE vString := vString || ',"(' || NumberToString(pGeom.SDO_POINT.X) || ',' || NumberToString(pGeom.SDO_POINT.Y) || ',' || NumberToString(pGeom.SDO_POINT.Z) || ')"'; END IF; -- ELEM_INFO IF (pGeom.SDO_ELEM_INFO IS NULL) THEN vString := vString || ','; ELSE vCount := pGeom.SDO_ELEM_INFO.COUNT; vString := vString || ',"{'; FOR i IN 1..vCount LOOP if i > 1 then vString := vString || ','; end if; vString := vString || emptytonull(NumberToString(pGeom.SDO_ELEM_INFO(i))); END LOOP; vString := vString || '}"'; END IF; -- ORDINATES IF (pGeom.SDO_ORDINATES IS NULL) THEN vString := vString || ','; ELSE vCount := pGeom.SDO_ORDINATES.COUNT; vString := vString || ',"{'; FOR i IN 1..vCount LOOP if i > 1 then vString := vString || ','; end if; vString := vString || emptytonull(NumberToString(pGeom.SDO_ORDINATES(i))); END LOOP; vString := vString || '}"'; END IF; RETURN '(' || vString || ')'; END; END pg_user_geom_util;
이것을 가지고, 옮겨감.
문제는 어떻게 옮겨갈 것인가인데, PosgreSQL 쪽에서는 oracle_fdw 뿐인듯하다.