by 지현명 [PostgreSQL 노하우/팁/자료] Postgresql TVP [2017.08.16 11:24:42]
CREATE TYPE public.employee_udt AS (
emp_id INTEGER,
emp_nm VARCHAR(40)
);
CREATE OR REPLACE FUNCTION public.usp_set_emp (
p_employee public.employee_udt []
)......생략...
---------------JAVA에서 구현하고 싶었던 부분
List lst_param = new ArrayList();
employee_udt emp = new employee_udt();
emp.emp_id = 4;
emp.emp_nm = "oracle";
lst_param.add(emp);
emp = new employee_udt();
emp.emp_id = 5;
emp.emp_nm = "Postgresql";
lst_param.add(emp);
db = DriverManager.getConnection(url, props);
cs = db.prepareCall("{call usp_set_emp(?)}");
Array inArray = db.createArrayOf("public.employee_udt", lst_param.toArray());
cs.setArray(1, inArray);
cs.execute();
Composite Type의 파라미터에 대해서 java jdbc 지원 안함.
외국 어느 개발자가 파싱을 java로 구현... (이렇게 하려면 차라리 json을 사용..)
http://tech.valgog.com/2009/02/passing-arrays-to-postgresql-database.html
-------------------
C#에서는 NPGSQL에서 Composite Type Array 를 사용할 경우 자동으로 변환해 주는데
JAVA JDBC에서는 자동변환을 지원하지 못합니다.(오늘까지 최신버전에서..)
JAVA에서만 해결 방법을 찾다가 POSTGRESQL에서 TABLE ROW를 어떻게 ARRAY로 변환 하는지 알아내면 될거 같아서 반대로 찾아 가 봤다.
--아래와 같이 TABLE ROW를 ARRAY로 변환.
--컬럼값 중 특수문자(스페이스) 에는 \"이 들어 간다.
SELECT ARRAY(SELECT ROW(emp_id,emp_nm) FROM employee);
{"(2,jinsun)","(3,sunju11)","(1,\"gwise best 1 \")"}
--열 전체를 할 경우
SELECT ARRAY(SELECT employee FROM employee);
그럼 위의 결과 값을 자바의 파라미터에서 사용해 보자.
--그러나 setValue부분에서 에러가 난다.(Eclipse에서..)
cs = db.prepareCall("{call usp_set_emp(?)}");
PGobject pgObject = new PGobject();
pgObject.setType("employee_udt[]");
pgObject.setValue("{"(2,jinsun)","(3,sunju11)","(1,\"gwise best 1 \")"}");
cs.setObject(1, pgObject);
cs.execute();
--그래서 NetBeans에 Postgresql 결과값을 똑같이 붙여 녛기 해봤다.
--NetBeans에서는 java형식에 맞게 자동으로 변환해 줬다.
-- 아래와 같이 특수문자를 표시하는게 pg와 java같의 차이다.
--아래값을 Eclipse에서 사용하면 정상으로 처리...이런거 보면 NetBeans가 좋은거 같기도 하고...
cs = db.prepareCall("{call usp_set_emp(?)}");
PGobject pgObject = new PGobject();
pgObject.setType("employee_udt[]");
pgObject.setValue("{\"(2,jinsun)\",\"(3,sunju11)\",\"(1,\\\"지현명 입니다.\\\")\"}");
cs.setObject(1, pgObject);
cs.execute();
문제는 위와 같이 파싱을 개발자가 해 줘야 하는데 (최신 버전의 PG JDBC에서는 지원 안함)
이렇게 파싱하면서 까지 이걸써야 하는지 ...
난 JAVA에서 꼭 PG 함수의 Input 파라미터를 Composite Type 로 사용하겠다면 위와 같이 파싱을 해야 한다.
결론은 JAVA를 사용한다면 PG함수 파라미터를 JSON 사용하자...
혹시 PG JDBC에서 Composite Type Array를 자동변환 해 주는 방법 알고 계신분은 연락 부탁 드립니다.~
p.s
Client는 C#을 사용하고 Application WebService를 JAVA로 사용할 경우 위와 같은 문제가 발생...
그래서 java에서는 json사용.... App WebService를 IIS(WCF)사용한다면 문제 없음..
C#에서 table 행을 JSON으로 변환 한 것은 pg jdbc에서도 잘 인식 된다.
Newtonsoft.Json 사용하여 아래와 같이 직렬화 해서 java App WebService에 보내면 됨...
string jsonString = JsonConvert.SerializeObject(lst_param);
--------------
위에 테스트를 하던중 내장형 자료형에 대해서는 사용 가능합니다.
아래 링크에 해당 테스트 부분 있습니다.
string, int....
http://tonaconsulting.com/postgres-and-multi-dimensions-arrays-in-jdbc/