pl/pgsql을 이용한 테이블 업데이트(Update)

기존의 테이블에 새로운 필드를 추가하고, 이 필드에 값을 넣어야 할 필요가 있습니다. 상황은 지적도가 저장된 테이블의 PNU 필드를 파싱해서 번지값을 만들어 저장해야 합니다. 예를 들어서 PNU가 ‘2911011200200470001’라면 ’47-1산’으로 만들어야 한다는 것입니다.

사용하는 데이터베이스가 PostgreSQL이므로 pl/pgsql을 이용하였는데요. cursor를 이용하는 방식과 cursor를 이용하지 않는 방식이 있는데.. 먼저 cursor를 이용하지 않는 방식은 아래와 같습니다.

DO $$
DECLARE
    r RECORD;
    n1 INTEGER;
    n2 INTEGER;
    s TEXT;
    v TEXT;
BEGIN
    FOR r IN SELECT * FROM ecl_cadastral LOOP
        n1 = substr(r.pnu, 12, 4)::INTEGER;
        n2 = substr(r.pnu, 16, 4)::INTEGER;
        s = substr(r.pnu, 11, 1);
        
        IF n2 = 0 THEN
            v = n1;
        ELSE
            v = n1 || '-' || n2;
        END IF;

        IF s = '2' THEN
            v = v || '산';
        END IF;

        UPDATE ecl_cadastral SET label = v WHERE fid = r.fid;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

동일한 기능으로 cursor를 이용하는 방식은 아래와 같습니다.

DO $$
DECLARE
    c CURSOR FOR SELECT * FROM ecl_cadastral;
    r RECORD;
    n1 INTEGER;
    n2 INTEGER;
    s TEXT;
    v TEXT;
BEGIN
    FOR r IN c LOOP
        n1 = substr(r.pnu, 12, 4)::INTEGER;
        n2 = substr(r.pnu, 16, 4)::INTEGER;
        s = substr(r.pnu, 11, 1);
        
        IF n2 = 0 THEN
            v = n1;
        ELSE
            v = n1 || '-' || n2;
        END IF;

        IF s = '2' THEN
            v = v || '산';
        END IF;

        UPDATE ecl_cadastral SET label = v WHERE CURRENT OF c;
    END LOOP;
END;
$$ LANGUAGE plpgsql;

속도는 cursor를 이용하는 방식이 약 20% 정도 빨랐습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다