Open source RDBMS인 PostgreSQL은 현재 9.1.3버전까지 나온 잘 만들어진 DBMS이지만 아주 큰 약점들이 있다. 오늘은 그중 하나인 계층형 쿼리 기능에 대한 해법을 말해보고자한다.
계층형 쿼리, Hierachical Query는 보통 조직도나 다단계 분류표 등의 구조를 나타내는데 쓰는 구문으로 Oracle RDBMS에서 "start with ~ connect by~"의 형태로 쓰며, 보통 "connect by"로 불리운다. 그런데 PostgreSQL에서는 계층형 쿼리를 쓰려면 추가 모듈을 설치해야 하는데, 이 모듈을 설치하면 쓸 수 있는 connectby라는 함수는 속도가 아주 느리다. 그래서 "connect by"를 따로 구현해 보았다.

입력받은 테이블과 컬럼 이름으로 "with recursive" 구문을 문자열로 만들어서 PL/pgSQL의 dynamic query를 이용해서 실행하고, 결과를 result set 형식으로 반환하는 방식이다.


create or replace udf_connect_by (tab_name varchar, key_name varchar, parent_key_name varchar, start_with varchar)
return SETOF record
as $$
declare
v_rowcnt integer;
v_query varchar;
begin
select count(*) into v_rowcnt
from pg_tables
where tablename = tab_name;

if v_rowcnt = 0 then
raise exception 'Invalid table name';
end if;

v_query := 'with recursive T1(select *, 1 as r_level, array[' || key_name || '::varchar] as r_path, false r_flag
from ' || tab_name || '
where ' || start_with || '
union all
select B.*, T1.r_level + 1 as r_level, array_append(T1.r_path, ' || key_name || '::varchar) as r_path, B.' || key_name || '::varchar = any(T1.r_path) as r_flag
from ' || tab_name || ' B, T1
where not r_flag
and B.' || parent_key_name || ' = T1.' || key_name || ')
select * from T1 order by T1.r_path ';

return query execute v_query;



end;
$$
language pl/pgsql
;



iPhone 에서 작성된 글입니다.


오라클을 주로 사용하던 이들은 다른 DBMS에서 아쉬운 것들이 몇가지 있죠. 현재 사용중인 PostgreSQL의 경우, 오라클의 자유로운 db link와 merge 등이 아주 그립습니다. 그래서 이 merge 기능을 대신하는 방법을 찾아봤습니다.

수정 가능한 WITH CTE 구문을 이용한 merge 기능 구현

WITH TEST AS (
UPDATE world_human A
SET cel_phone = B.cel_phone, email_addr = B.email_addr
FROM servay B
WHERE A.human_id = B.human_id
RETURNING A.*)
INSERT INTO world_human(human_id, cel_phone, email_addr)
SELECT C.human_id, C.cel_phone, C.email_addr
FROM servay C
WHERE C.human_id NOT IN (SELECT human_id FROM TEST)
;

이렇게하면 MERGE와 동일하게 입력 및 수정을 하나의 쿼리로 실행할 수 있습니다.

아 조건이 하나있는데, PostgreSQL 버전이 9.1.3이어야합니다. 9.0 버전에서는 안되는걸 테스트와 메뉴얼로 확인 했습니다. 9.1.2나 9.1.1에서도 잘 되는지는 확인을 못 했습니다.

iPhone 에서 작성된 글입니다.
약 3주일 정도 PostgreSQL을 써본 감상.

뭐랄까 이것 저것 다 되는듯하면서 안 되거나 모양새가 묘하네요.
디비 링크가 좀 불편하고요. 뭐 아직 방법을 못 찾은거닐수도 있지만요...
음 열심히 공부 중 입니다.

iPhone 에서 작성된 글입니다.
 이 글은 Naver cafe SQLROAD카페(MSSQL전문가로가는지름길)에 올렸던 글에 좀더 살을 붙인 글입니다.

 MS SQL Server를 운영하는 중에 이기종 DBMS에서 data를 가져올 일이 꽤 많죠. DW 구축을 위해 도입한 ETL Tool이 있다면 이런 일이 다른 팀에 생색내며 해줄 수 있는 좋은 건수가 될텐데요. 대부분의 경우 이런 경우 PHP 같은 스크립트 언어를 이용해서 data를 넘기도록 만들거나, 해당 DB에 Tool로 접속하여 엑셀 파일 형태로 data를 뽑아낸뒤 다시 업로드하는 방식을 이용하는걸로 알고 있습니다. 조금 번거롭죠...
이건 SQL Server를 운영하는 DBA만의 고민은 아닐겁니다. 이번엔 SQL Server를 운영하다가 PostgreSQL의 Data를 가져올때 어떻게 하나... 하는 얘기를 해볼까합니다. Oracle, Tibero와 data를 공유하는 것에 대해서는 이전에 올린 글들을 찾아보시면 될것 같습니다. 이번에는 PostgreSQL입니다.

 제가 올렸던 SQL Server 관련 글들을 보시면 아시겠지만, 저는 OLEDB, ODBC 드라이버를 이용해서 SSIS 혹은 Openquery를 쓰는 방식을 얘기할 생각입니다.

1. ODBC, OLEDB driver 설치하기.
 PostgreSQL 홈페이지(www.postgresql.org)에서 다운로드 메뉴로 들어가면 "Driver and interface"라는 항목이 있습니다. (바로가기)
 OLEDB driver가 몇가지 있지만 저는 PostgreSQL OLE DB Provider project에서 제공하는 PostgreSQL OLE DB Provider for Windows를 이용하였습니다. 이유는 오픈소스라서입니다. PostgreSQL Native OLEDB Provider (PGNP)라는게 있는데 최근까지 업데이트도 되고 SQL Server 200의 DTS와 2005/2008의 SSIS 그리고 복제 등에서 사용할 수 있다고 소개되어있네요. 문제는 Trial 버전이라는겁니다. 아직 Manual과 홈페지이를 다 확인하지는 못했지만, 제약이 있을것 같네요.

 

2. Linked server(연결된 서버)를 이용한 Openquery 사용하기
 Openquery는

3. SSIS로 data 가져오기
 설치한 OLEDB 드라이버를 통해서 PostrgeSQL에 접속할 수 있습니다.
아래의 그림은 SQL Server 2008 버전의 SQL Server Management Studio에서 SSIS를 사용할 때 데이터 원본 선택 화면입니다.

SQL Server 가져오기 및 내보내기 마법사


위에서 PostgreSQL OLEDB driver를 선택하면 아래와 같은 화면이 보입니다.


위에서 한 뒤 연결 속성을 클릭하면 아래와 같이 창이 뜹니다. 여기서 PostgreSQL 정보를 입력하면 해당 DB에 접속이 가능합니다.

 여기서부터는 PGNP Provider를 설치하고 SSIS를 사용할때의 화면입니다. 뭐... 별로 다른점은 없어 보입니다.
화면이 달라 보인다면 그건 위의 화면은 Windows 2003 Test server에서 캡쳐한 화면이고, 아래는 Windows 7 Test PC에서 캠쳐한 화면이라는 겁니다.


SSIS 사용에 대해서는 다음에 따로 정리하도록 하겠습니다.
그럼 이만...





+ Recent posts