Category Archives: Data

Apache Storm 사용기 -> 포기(Flink로 전환)

Clojure로 코어를 만들었다는데서관심을 가졌으나최신버전인 2.0.0에서는 Java로 컨버팅 되어 버렸다는 슬픈 소식

python, clojure, java, shell script 폴리글랏이라고 했으나python코드는 별로 쓸모없는 포인트만 먹고 있다. 빼버리면 좋겠는데
실행 파라미터체크하는 정도 코드만 있다. 스톰 토폴로지를 파이썬으로도 만들 수 있다고되어 있는 것 같은데… 별로 그럴 생각은 없어서..
이 부분을 제외하고 자바와 설정파일을 이용하는게 여러 환경에 배포하는데도 편리하고 좋을 것 같다

intellij로 열려고 하는데 잘 안열린다.uber-jar 돼지자르를 만들 때 사용하는 shade-deps로 인한 임포트오류가 발생

Storm에서 한개의 실행단위를 topology라고 하는데 이걸 로컬에서 실행테스트도 해보고 디버깅도 해보고 로그도 찍어보고 하고싶은데… 다 쉽지 않다.
유닛테스트, 로컬실행, 디버깅 환경부터 만들어야 뭘 제대로 쓸 수 있을 것 같다.

문서…
이것저것 써 있기는 한데
고인물파티같은 느낌
한국 커뮤니티도 없다.
Flink만 쓰는건가
인터페이스단위로 분석해놓은 문서조차 없다
튜토리얼이나 예제가 있긴한데 딱 맞는 분석사례만 있는게 아니니까.. 결국 분석해서 써야된다

코틀린도 그랬지만… 초기에는 불만이 많은 편이라
좀 더 써 봐야지 판단할 수 있겠다


프로젝트에 적용을 시도했으나

Flink로 전환하려고 한다

  • 유닛테스트 지원안됨
  • 연동테스트 지원안됨
  • 로컬 데몬이 자꾸 죽음
  • Flink보다 업데이트가 안되고 있음
  • Flink보다 커뮤니티가 약함
  • 1에서 2로 메이저 업데이트 되면서 도큐먼트 링크가 다 죽음(2버전이지만 invator나 마찬가지인 상태)
  • 실행스크립트에 파이썬이 혼용되는 등 불필요한 프로젝트 복잡도가 증가함.
  • ide에서 실행이 안됨(디버깅 불가. flink에서는 되는지는 모르겠다)
  • maven-shade와 fat-jar(uber-jar)사용으로 배포 불편.
    — 이게 java jar –classpath로 실행하면서 storm.jar와 {user-topology}.jar를 실행시켜서 shade도 필요하고 그런건데 굉장히 쨔증난다 .설계가 잘못됐다고 본다.
  • 마찬가지로 maven-shade와 fat-jar(uber-jar) 사용으로 ide에서 본 프로젝트가 열리지도 않음
    — 억지로 열려면 mvn package한 다음에 shade에서 생성된 jar를 ide에서 합치면 됨
    —- 이런 문제가 있으면 프로젝트를 분리해놓던가 해야될 것 같은데 개발진들 열의가 별로 없어보임. 메이븐 의존성도 다 옛날거라 kafka client 0.8.0이었나
  • 로깅이 잘 안되는걸 빼먹을 뻔 했군
    토폴로지 jar에 포함시켜놓을 수 있으면 좋겠는데 그런 부분이 잘 안되는 것 같다
  • 로컬테스트용과 리모트배포용 코드를 아예 따로 작성해야된다. 이건 진짜 문제있다. ifelse로 분기 할 수도 있지만… 좀 참기힘든 부분이자너

또 다른 선택지

  1. Apache Flink
  2. Apache Apex
  3. Apache Spark – Streaming
  4. Apache Heron
  5. Uber AthenaX
    https://github.com/uber/AthenaX

아파치에서만 몇개야…. Storm은 죽은 프로젝트다. Heron(Incubator)이 스톰 뒤를 이어서 개발중인 것으로 보인다.

관련기술

  1. Apache Druid
    https://druid.apache.org/
  2. Apache Calcite
    https://calcite.apache.org/

PostgreSQL 9.5 초기설정

기본설정은 버전이 변경되도 크게 바뀌지 않는다

설정파일

postgresql.conf

https://www.postgresql.org/docs/9.5/static/runtime-config-connection.html

사용자가 늘어서 튜닝을 해야한다 하는상황이 아니라면 
이거말구 크게 바꿀게 없다.
listen_addresses = 'localhost'
listen_addresses = '*'
listen_addresses = '192.168.0.2,localhost'
listen_addresses = '127.0.0.1'

pg_hba.conf

  • https://www.postgresql.org/docs/9.1/static/auth-pg-hba-conf.html
개발용이면 보통은 이거한줄 추가하지 않을까
host    all             all             127.0.0.1/0             md5
운영서버라면 서버 ip를 명시하면 되고

서버 범위 지정하는거면 ip주소 쓰는칸에
192.168.0.0/24

터미널접속

sudo -u postgres psql -U postgres -w

사용자 관리

사용자 목록보기
postgres=# \deu
postgres=# \du

create user ${my-user} with password '${my-password}';
create database ${my-database};
grant all privileges on database ${my-database} to ${my-user};

권한문제 나올 때
create user --superuser ${my-user}
alter role ${my-user} superuser;
관리자권한 줘버리는거나 껄쩍지근하기도 한데...
완료후 권한축소
alter role ${my-user} nosuperuser;

H2 Database – 관련정보

인메모리로 실행시켰을 때 접속할 수 있도록 하는 빈
주소 : http://localhost:8080/console

    @Bean
    fun h2ServletRegistration(): ServletRegistrationBean {
        val bean = ServletRegistrationBean(WebServlet())
        bean.addUrlMappings("/console/*")
        return bean
    }

그런데 in-memory 실행 시킬때는 콘솔접속 하지말고 그냥 stand alone 실행시켜서 접속하는게 낫지 않나

in-memory connection info

jdbc:h2:mem:{디비이름 암거나지정}

url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
name: {name of data source}
username: sa
password: {empty}

MongoDB 특성 분석 01, 사용전 기능조사~ 에서 ~ 적용사례까지

개요

몽고디비는 처음 알게됐을 때 부터 써보고싶기는 했는데.. SI만 하다보니 쓸 기회가 없었다.
개인적으로 테스트용이나 회사에서 간단한 모듈을 만들 때 사용하긴 했지만, 제대로 분석을 해 보고 적용해본게 아니라서 깊이있는 지식은 없는 상태

사용목적

기술적으로 몽고디비가 꼭 필요한 상황은 아니라고 판단되지만… 나쁜 선택은 아닐 것 같아서 일단 적용 해 볼 생각이다.
저장할 데이터 : Crawling, Scrapping 데이터, 게시판 글, 댓글, GIS정보, GridFS를 이용한 이미지 저장

 

GIS 정보 관리
PostgreSQL의 PostGIS를 써도 되지만…. 내부정보가 아닌 사용자 데이터를 저장해야 한다. 서비스가 급성장하면서 데이터가 엄청나게 쌓일거라서 MongoDB를 쓸 수 밖에 없잖아

Crawling, Scrapping 데이터
텍스트 파일 저장

GridFS를 이용한 이미지 저장
이 부분은 써야할까? 모르겠다. 성능문제도… 별 생각없이봐도 문제가 잇겠지?
http://symplog.tistory.com/entry/MongoDB-MongoDB-GridFS-%EB%B6%80%ED%95%98%ED%85%8C%EC%8A%A4%ED%8A%B8
있다고하네…
그리고 cdn에 올리면 필요없는 부분 아닌가

몽고디비에 대해 잘 정리된 페이지
http://kkyunstory.tistory.com/65
이런 평가를 많이 보긴 했는데…

아몰랑 그냥 쓰다가 안되는거 한개씩 옮겨야겠다.

특성 ~~ 확인중

문서형 데이터베이스

데이터를 문서형태로 저장 – BSON을 이용하여 저장
BSON : JSON을 Binary 형태로 저장

장점

다양한 인덱스 제공
Sharding

 

인덱싱 방법

종류

Unique고유 인덱스
Sparse희소 인덱스 : Null인 경우 인덱스 생성하지 않음
다중 키 인덱스, 복합인덱스

주의점

롤백은 불가능
트랜잭션 안된다고 치고
인덱싱 걸면 디비 먹통

MSSQL2008 -> Oracle12c Sqldeveloper이용 데이터 대강이전

어쩌다 보니 어느패션업체의 디비 마이그레이션업무를 처리하게 됐다.
직접 말한것은 아니고 기획자를 통해서 한다리 건너서 협의가 이뤄져서 정확히는 모르겠지만
전달받기로는 마이그레이션이 쉬운게 아니라고 설명을 하면 “그냥 해주면 안되요?” 라는 반응을 보였다는 것 같다.

고객사에서는 마이그레이션을 그냥 파일 카피 정도로 생각하는 것 아닐까?
내가 갔으면 말도안되다는것을 좀 더 강하게 어필했을 것 같은데…

디비 전환 이유는 …. 정확히 전달받지는 못했지만 데이터를 보니까 이해가 갔다.
데이터 상태를 보니 속도가 매우 느렸을 것 같다.
검색도 하지 않을 것 같은 로그테이블이 동일한 데이터베이스에 수백기가 쌓여 있었다
MSSQL이 느리니까 짷좋은 오라클로 옮기면 빨라지겠지? 정도의 판단이 아니었을까

그리고 기왕 마이그레이션을 하기로 마음을 먹었으면 안쓰는 테이블이라던가 프로시저들을 파악해서 정리를 하면 좋을텐데…

대~애충 빨리 해다라고 하니 그럴 수 밖에…

마이그레이션은 툴을 이용해서 처리하기로 했다.
유료는 안 써봐서 모르겠고 이전에도 몇 번 돌려봤는데 특정 쿼리문은 번역도 안되고 테이블도 몇 개씩 빼먹고 하는 경우가 많았다.
각 데이터베이스에 의존적인 키워드를 사용하는 경우 오류도 발생하고

툴은 SqlDeveloper 4.1.5를 사용하기로 결정
(고객사에서 추가비용 지출을 저언혀 생각하지 않고 있어서)

SqlDevelop – Tools – Database – Third Party JDBC Driver에 추가

jtds-1.3.1-dist

이래저래 필요한 셋팅하고서 마이그레이션 실행
오류가 이것저것 많이 발생했는데 주로 발생하는 문제는 인코딩 오류, 쿼리오류
인코딩은 초반에 잡아줘서 해결했지만.. 쿼리는… 일부는 포기하고 넘어갔다.

MSSQL 2008 -> Oracle12c
결과 : 쓸데없는 테이블을 생성 해 놓는다. 마이그레이션 결과기록 테이블인가?
데이터는 제대로 옮겨지지 않는다. (뭘 잘못한 것 같진 않고 12는 아직 지원되지 않는것 같다)

MSSQL2008 -> Oracle11gr2
결과 : 테이블과 데이터는 잘 옮겨졌다

Oracle11gr2 -> Oracle12c
여기서는 자동화 툴이 안돌아가고 쿼리로 백업받은 후에 다시 올렸다.
덤프는 뭔가 호환이 안되는 것 같다.
이 방법으로 하는경우 Clob은 이전이 안된다. Oracle Clob은 쿼리 insert가 안되서 Varchar4000으로 변경할 수 있는 부분은 변경하고 안되는 부분은 python script를 이용해서 처리했다.

 

야매이전 완료 후

Function, Procedure – 거의 다 깨진다.
View – 거의못쓸지경.. 다 지우는게 나을 것 같다
Table-Clob제외하고는 정상

처참하네.. 마이그레이션이라고 할 수 있을까?
오류가 날 대 마다 거의 다 손으로 처리해야하지 않을까 싶다.

일 해 놓고도 미안한 상황이다
정식 프로젝트가 아니라 더 시간을 할애할 수는 없으니 대강 마무리할 수 밖에…

Oracle 디비 백업 – expdp

expdp system/oracle@orcl directory=MY_DATA_PUMP dumpfile=shopmall.dump logfile=shopmall.dump schemas=shopmalljob_name=shopmall001

이 명령을 실행시키면..

Export: Release 12.1.0.2.0 - Production on Tue Dec 13 15:04:01 2016

Copyright (c) 1982, 2015, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 12c Standard Edition Release 12.1.0.2.0 - 64bit Production

UDE-31623: operation generated ORACLE error 31623
ORA-31623: a job is not attached to this session via the specified handle
ORA-06512: at "SYS.DBMS_DATAPUMP", line 3905
ORA-06512: at "SYS.DBMS_DATAPUMP", line 5203
ORA-06512: at line 1

다음 경고가 뜨면서 처리되지 않는다.

 

1. 이미 처리중이던 녀석이 남아있으면 안될 수 있다고

이걸 확인 해 보라는데…

select * frmo dba_datapump_jobs

데이터가 있을 경우 삭제
drop table ownername.jobname

 

또 안되네

2. 스트림 풀 사이즈를 늘려보라는데

SQL> show parameter streams_pool;

NAME                                 TYPE             VALUE
------------------------------------ ----------- ------------------------------
streams_pool_size                    big integer      0


SQL> alter system set streams_pool_size=1G scope=both;

SQL> show parameter aq
 
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
aq_tm_processes                      integer     0
SQL> alter system set aq_tm_processes=1 scope=both;

안된다

3. DBA 디렉토리 등록

SQL> select * from dba_directories;

OWNER
--------------------------------------------------------------------------------
DIRECTORY_NAME
--------------------------------------------------------------------------------
DIRECTORY_PATH
--------------------------------------------------------------------------------
ORIGIN_CON_ID
-------------
SYS
MY_DATA_PUMP
/data2

이건 등록되어있는 상태다

신규등록하려면
SQL> create directory MY_DATA_PUMP as '/home/datapump'
SQL> grant read, write on directory MY_DATA_PUMP to SYSTEM;
SQL> GRANT CREATE ANY DIRECTORY TO SYSTEM;
SQL> SELECT * FROM DBA_DIRECTORIES;
확인~

 

https://oracleexamples.wordpress.com/2010/02/17/expdp-error-31623-and-ora-12805-in-cluster-10-2-0-4/


-
 
@$ORACLE_HOME/rdbms/admin/catdph.sql
 
@$ORACLE_HOME/rdbms/admin/prvtdtde.plb
 
@$ORACLE_HOME/rdbms/admin/catdpb.sql
 
@$ORACLE_HOME/rdbms/admin/dbmspump.sql
 
@$ORACLE_HOME/rdbms/admin/utlrp.sql

안되네.. 중간중간오류

아직안됨…디비 깨짔나

 

질문할만한사이트가…

http://www.gurubee.net/
http://www.dator.co.kr/
http://www.dbguide.net/
http://database.sarang.net/

 

몇가지 더 확인 필요해 보이는 부분

http://www.dba-oracle.com/t_ora_31623_job_not_attached_to_session_via_specified_handle.htm

http://theone79.tistory.com/837

Oracle – python 연동

Oracle은 별로 쓰고싶지 않은데…  또…

이번엔 clob 데이터 문제… mssql의 데이터를 oracle로 옮겨야되는데… clob자료형이다.
sql developer에서 insert query로 뽑아내서 옮기려고 하는데 clob라서 안된다.
python으로 스크립트를 짜서 처리를 하려고 하는데~~

Oracle은 만만한 녀석이 아니다.

프로세스 진행상황을 순차적으로 기록하면

1. MS-SQL 연동(은 덤으로)

pymssql을 설치하니까 간단히 연동이 된다.

import pymssql

conn = pymssql.connect(server='ipiphosthost', user='username', password='pwd_passwddddrd', database='dbnanmmnell')
cursor = conn.cursor()
cursor.execute('SELECT top 100 * FROM prod')
row = cursor.fetchone()
while row:
    print(str(row[0]) + " " + str(row[1]) + " " + str(row[2]) + " " + str(row[3]))
    row = cursor.fetchone()

바로 잘 돌아간다.

단, 내 컴퓨터에는

Visual Studio 2015, MSSQL(sql server 2008 r2)서버가 설치되어 있다. 조건이 다르다면 바로 안될수도 있다.

 

 

2. Oracle 연동

import cx_Oracle

PORT_NUM = 1521
dsn = cx_Oracle.makedsn("SERVER_HOST", PORT_NUM, "ORCLE_SID_NAME")
db = cx_Oracle.connect("USERNAME", "PASSWORD", dsn)
cursor = db.cursor()

cursor.execute("""SELECT * FROM sso_data.t_users where rownum < 100""")
row = cursor.fetchone()
while row:
    print(str(row[0]) + " " + str(row[1]) + " " + str(row[2]) + " " + str(row[3]))
    row = cursor.fetchone()

샘플코드는 이렇다.

도큐먼트 : http://cx-oracle.readthedocs.io/en/latest/index.html

 

오라클답게 쉽게 설치되지 않는다.
pip install cx_Oracle

pip로 설치후에 발견되는 에러
ImportError:DLL load failed:지정된 프로시저를 찾을 수 없습니다.
InterfaceError:Unable to acquire Oracle environment handle

 

위에러가 자꾸 나와서.

oracle instant client설치
C:\oracle\instantclient_12_1 이 경로에 설치 해 주고 path 잡아줬다.

cx_Oracle 설치
https://pypi.python.org/pypi/cx_Oracle/5.2.1 여기서 받아다가 설치

설치할 때 32/64비트 그리고 파이썬 버전을 잘 맞춰야된다.
오라클 버전도..

며칠 지났다고 기억이 안나네

DatabaseMetaData 클래스로 메타데이터 확인

코드

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;


/**
 * @author archmagece
 * @with pizzahut-parent
 * @since 2016-11-08
 */
public class DBMetaTest {
	public static void main(String[] args)
	{
		try{
			Class.forName("oracle.jdbc.OracleDriver");
			Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ODRDB","username","password");
			DatabaseMetaData metadata = connection.getMetaData();

			System.out.println("allProceduresAreCallable : "+ metadata.allProceduresAreCallable());
			System.out.println("allTablesAreSelectable : "+ metadata.allTablesAreSelectable());
			System.out.println("URL : "+ metadata.getURL());
			System.out.println("UserName : "+ metadata.getUserName());
			System.out.println("isReadOnly : "+ metadata.isReadOnly());
			System.out.println("nullsAreSortedHigh : "+ metadata.nullsAreSortedHigh());
			System.out.println("nullsAreSortedLow : "+ metadata.nullsAreSortedLow());
			System.out.println("nullsAreSortedAtStart : "+ metadata.nullsAreSortedAtStart());
			System.out.println("nullsAreSortedAtEnd : "+ metadata.nullsAreSortedAtEnd());
			System.out.println("getDatabaseProductName : "+ metadata.getDatabaseProductName());
			System.out.println("getDatabaseProductVersion : "+ metadata.getDatabaseProductVersion());
			System.out.println("getDriverName : "+ metadata.getDriverName());
			System.out.println("getDriverVersion : "+ metadata.getDriverVersion());
			System.out.println("getDriverMajorVersion : "+ metadata.getDriverMajorVersion());
			System.out.println("getDriverMinorVersion : "+ metadata.getDriverMinorVersion());
			System.out.println("usesLocalFiles : "+ metadata.usesLocalFiles());
			System.out.println("usesLocalFilePerTable : "+ metadata.usesLocalFilePerTable());
			System.out.println("supportsMixedCaseIdentifiers : "+ metadata.supportsMixedCaseIdentifiers());
			System.out.println("storesUpperCaseIdentifiers : "+ metadata.storesUpperCaseIdentifiers());
			System.out.println("storesLowerCaseIdentifiers : "+ metadata.storesLowerCaseIdentifiers());
			System.out.println("storesMixedCaseIdentifiers : "+ metadata.storesMixedCaseIdentifiers());
			System.out.println("supportsMixedCaseQuotedIdentifiers : "+ metadata.supportsMixedCaseQuotedIdentifiers());
			System.out.println("storesUpperCaseQuotedIdentifiers : "+ metadata.storesUpperCaseQuotedIdentifiers());
			System.out.println("storesLowerCaseQuotedIdentifiers : "+ metadata.storesLowerCaseQuotedIdentifiers());
			System.out.println("storesMixedCaseQuotedIdentifiers : "+ metadata.storesMixedCaseQuotedIdentifiers());
			System.out.println("getIdentifierQuoteString : "+ metadata.getIdentifierQuoteString());
			System.out.println("getSQLKeywords : "+ metadata.getSQLKeywords());
			System.out.println("getNumericFunctions : "+ metadata.getNumericFunctions());
			System.out.println("getStringFunctions : "+ metadata.getStringFunctions());
			System.out.println("getSystemFunctions : "+ metadata.getSystemFunctions());
			System.out.println("getTimeDateFunctions : "+ metadata.getTimeDateFunctions());
			System.out.println("getSearchStringEscape : "+ metadata.getSearchStringEscape());
			System.out.println("getExtraNameCharacters : "+ metadata.getExtraNameCharacters());
			System.out.println("supportsAlterTableWithAddColumn : "+ metadata.supportsAlterTableWithAddColumn());
			System.out.println("supportsAlterTableWithDropColumn : "+ metadata.supportsAlterTableWithDropColumn());
			System.out.println("supportsColumnAliasing : "+ metadata.supportsColumnAliasing());
			System.out.println("nullPlusNonNullIsNull : "+ metadata.nullPlusNonNullIsNull());
			System.out.println("supportsConvert : "+ metadata.supportsConvert());
			//supportsConvert(i" : "+ nt fromType, int toType)
			System.out.println("supportsTableCorrelationNames : "+ metadata.supportsTableCorrelationNames());
			System.out.println("supportsDifferentTableCorrelationNames : "+ metadata.supportsDifferentTableCorrelationNames());
			System.out.println("supportsExpressionsInOrderBy : "+ metadata.supportsExpressionsInOrderBy());
			System.out.println("supportsOrderByUnrelated : "+ metadata.supportsOrderByUnrelated());
			System.out.println("supportsGroupBy : "+ metadata.supportsGroupBy());
			System.out.println("supportsGroupByUnrelated : "+ metadata.supportsGroupByUnrelated());
			System.out.println("supportsGroupByBeyondSelect : "+ metadata.supportsGroupByBeyondSelect());
			System.out.println("supportsLikeEscapeClause : "+ metadata.supportsLikeEscapeClause());
			System.out.println("supportsMultipleResultSets : "+ metadata.supportsMultipleResultSets());
			System.out.println("supportsMultipleTransactions : "+ metadata.supportsMultipleTransactions());
			System.out.println("supportsNonNullableColumns : "+ metadata.supportsNonNullableColumns());
			System.out.println("supportsMinimumSQLGrammar : "+ metadata.supportsMinimumSQLGrammar());
			System.out.println("supportsCoreSQLGrammar : "+ metadata.supportsCoreSQLGrammar());
			System.out.println("supportsExtendedSQLGrammar : "+ metadata.supportsExtendedSQLGrammar());
			System.out.println("supportsANSI92EntryLevelSQL : "+ metadata.supportsANSI92EntryLevelSQL());
			System.out.println("supportsANSI92IntermediateSQL : "+ metadata.supportsANSI92IntermediateSQL());
			System.out.println("supportsANSI92FullSQL : "+ metadata.supportsANSI92FullSQL());
			System.out.println("supportsIntegrityEnhancementFacility : "+ metadata.supportsIntegrityEnhancementFacility());
			System.out.println("supportsOuterJoins : "+ metadata.supportsOuterJoins());
			System.out.println("supportsFullOuterJoins: "+ metadata.supportsFullOuterJoins());
			System.out.println("supportsLimitedOuterJoins : "+ metadata.supportsLimitedOuterJoins());
			System.out.println("getSchemaTerm : "+ metadata.getSchemaTerm());
			System.out.println("getProcedureTerm : "+ metadata.getProcedureTerm());
			System.out.println("getCatalogTerm : "+ metadata.getCatalogTerm());
			System.out.println("isCatalogAtStart : "+ metadata.isCatalogAtStart());
			System.out.println("getCatalogSeparator : "+ metadata.getCatalogSeparator());
			System.out.println("supportsSchemasInDataManipulation : "+ metadata.supportsSchemasInDataManipulation());
			System.out.println("supportsSchemasInProcedureCalls : "+ metadata.supportsSchemasInProcedureCalls());
			System.out.println("supportsSchemasInTableDefinitions : "+ metadata.supportsSchemasInTableDefinitions());
			System.out.println("supportsSchemasInIndexDefinitions : "+ metadata.supportsSchemasInIndexDefinitions());
			System.out.println("supportsSchemasInPrivilegeDefinitions : "+ metadata.supportsSchemasInPrivilegeDefinitions());
			System.out.println("supportsCatalogsInDataManipulation : "+ metadata.supportsCatalogsInDataManipulation());
			System.out.println("supportsCatalogsInProcedureCalls : "+ metadata.supportsCatalogsInProcedureCalls());
			System.out.println("supportsCatalogsInTableDefinitions : "+ metadata.supportsCatalogsInTableDefinitions());
			System.out.println("supportsCatalogsInIndexDefinitions : "+ metadata.supportsCatalogsInIndexDefinitions());
			System.out.println("supportsCatalogsInPrivilegeDefinitions : "+ metadata.supportsCatalogsInPrivilegeDefinitions());
			System.out.println("supportsPositionedDelete : "+ metadata.supportsPositionedDelete());
			System.out.println("supportsPositionedUpdate : "+ metadata.supportsPositionedUpdate());
			System.out.println("supportsSelectForUpdate : "+ metadata.supportsSelectForUpdate());
			System.out.println("supportsStoredProcedures : "+ metadata.supportsStoredProcedures());
			System.out.println("supportsSubqueriesInComparisons : "+ metadata.supportsSubqueriesInComparisons());
			System.out.println("supportsSubqueriesInExists : "+ metadata.supportsSubqueriesInExists());
			System.out.println("supportsSubqueriesInIns : "+ metadata.supportsSubqueriesInIns());
			System.out.println("supportsSubqueriesInQuantifieds : "+ metadata.supportsSubqueriesInQuantifieds());
			System.out.println("supportsCorrelatedSubqueries : "+ metadata.supportsCorrelatedSubqueries());
			System.out.println("supportsUnion : "+ metadata.supportsUnion());
			System.out.println("supportsUnionAll : "+ metadata.supportsUnionAll());
			System.out.println("supportsOpenCursorsAcrossCommit : "+ metadata.supportsOpenCursorsAcrossCommit());
			System.out.println("supportsOpenCursorsAcrossRollback : "+ metadata.supportsOpenCursorsAcrossRollback());
			System.out.println("supportsOpenStatementsAcrossCommit : "+ metadata.supportsOpenStatementsAcrossCommit());
			System.out.println("supportsOpenStatementsAcrossRollback : "+ metadata.supportsOpenStatementsAcrossRollback());
			System.out.println("getMaxBinaryLiteralLength : "+ metadata.getMaxBinaryLiteralLength());
			System.out.println("getMaxCharLiteralLength : "+ metadata.getMaxCharLiteralLength());
			System.out.println("getMaxColumnNameLength : "+ metadata.getMaxColumnNameLength());
			System.out.println("getMaxColumnsInGroupBy : "+ metadata.getMaxColumnsInGroupBy());
			System.out.println("getMaxColumnsInIndex : "+ metadata.getMaxColumnsInIndex());
			System.out.println("getMaxColumnsInOrderBy : "+ metadata.getMaxColumnsInOrderBy());
			System.out.println("getMaxColumnsInSelect : "+ metadata.getMaxColumnsInSelect());
			System.out.println("getMaxColumnsInTable : "+ metadata.getMaxColumnsInTable());
			System.out.println("getMaxConnections : "+ metadata.getMaxConnections());
			System.out.println("getMaxCursorNameLength : "+ metadata.getMaxCursorNameLength());
			System.out.println("getMaxIndexLength : "+ metadata.getMaxIndexLength());
			System.out.println("getMaxSchemaNameLength : "+ metadata.getMaxSchemaNameLength());
			System.out.println("getMaxProcedureNameLength : "+ metadata.getMaxProcedureNameLength());
			System.out.println("getMaxCatalogNameLength : "+ metadata.getMaxCatalogNameLength());
			System.out.println("getMaxRowSize : "+ metadata.getMaxRowSize());
			System.out.println("doesMaxRowSizeIncludeBlobs : "+ metadata.doesMaxRowSizeIncludeBlobs());
			System.out.println("getMaxStatementLength : "+ metadata.getMaxStatementLength());
			System.out.println("getMaxStatements : "+ metadata.getMaxStatements());
			System.out.println("getMaxTableNameLength : "+ metadata.getMaxTableNameLength());
			System.out.println("getMaxTablesInSelect : "+ metadata.getMaxTablesInSelect());
			System.out.println("getMaxUserNameLength : "+ metadata.getMaxUserNameLength());
			System.out.println("getDefaultTransactionIsolation : "+ metadata.getDefaultTransactionIsolation());
			System.out.println("supportsTransactions : "+ metadata.supportsTransactions());
//			System.out.println(" : "+ metadata.supportsTransactionIsolationLevel());
			System.out.println("supportsDataDefinitionAndDataManipulationTransactions : "+ metadata.supportsDataDefinitionAndDataManipulationTransactions());
			System.out.println("supportsDataManipulationTransactionsOnly : "+ metadata.supportsDataManipulationTransactionsOnly());
			System.out.println("dataDefinitionCausesTransactionCommit : "+ metadata.dataDefinitionCausesTransactionCommit());
			System.out.println("dataDefinitionIgnoredInTransactions : "+ metadata.dataDefinitionIgnoredInTransactions());
//			System.out.println(" : "+ metadata.getProcedures());
//			System.out.println(" : "+ metadata.getProcedureColumns());
//			System.out.println(" : "+ metadata.getTables());
//			System.out.println(" : "+ metadata.getSchemas());
//			System.out.println(" : "+ metadata.getCatalogs());
//			System.out.println(" : "+ metadata.getTableTypes());
//			System.out.println(" : "+ metadata.getColumns());
//			System.out.println(" : "+ metadata.getColumnPrivileges());
//			System.out.println(" : "+ metadata.getTablePrivileges());
//			System.out.println(" : "+ metadata.getBestRowIdentifier());
//			System.out.println(" : "+ metadata.getVersionColumns());
//			System.out.println(" : "+ metadata.getPrimaryKeys());
//			System.out.println(" : "+ metadata.getImportedKeys());
//			System.out.println(" : "+ metadata.getExportedKeys());
//			System.out.println(" : "+ metadata.getCrossReference());
//			System.out.println(" : "+ metadata.getTypeInfo());
//			System.out.println(" : "+ metadata.getIndexInfo());
//			System.out.println(" : "+ metadata.supportsResultSetType());
//			System.out.println(" : "+ metadata.supportsResultSetConcurrency());
//			System.out.println(" : "+ metadata.ownUpdatesAreVisible());
//			System.out.println(" : "+ metadata.ownDeletesAreVisible());
//			System.out.println(" : "+ metadata.ownInsertsAreVisible());
//			System.out.println(" : "+ metadata.othersUpdatesAreVisible());
//			System.out.println(" : "+ metadata.othersDeletesAreVisible());
//			System.out.println(" : "+ metadata.othersInsertsAreVisible());
//			System.out.println(" : "+ metadata.updatesAreDetected());
//			System.out.println(" : "+ metadata.deletesAreDetected());
//			System.out.println(" : "+ metadata.insertsAreDetected());
			System.out.println("supportsBatchUpdates : "+ metadata.supportsBatchUpdates());
//			System.out.println(" : "+ metadata.getUDTs());
			System.out.println("getConnection : "+ metadata.getConnection());
			System.out.println("supportsSavepoints : "+ metadata.supportsSavepoints());
			System.out.println("supportsNamedParameters : "+ metadata.supportsNamedParameters());
			System.out.println("supportsMultipleOpenResults : "+ metadata.supportsMultipleOpenResults());
			System.out.println("supportsGetGeneratedKeys : "+ metadata.supportsGetGeneratedKeys());
//			System.out.println(" : "+ metadata.getSuperTypes());
//			System.out.println(" : "+ metadata.getSuperTables());
//			System.out.println(" : "+ metadata.getAttributes());
//			System.out.println(" : "+ metadata.supportsResultSetHoldability());
			System.out.println("getResultSetHoldability : "+ metadata.getResultSetHoldability());
			System.out.println("getDatabaseMajorVersion : "+ metadata.getDatabaseMajorVersion());
			System.out.println("getDatabaseMinorVersion : "+ metadata.getDatabaseMinorVersion());
			System.out.println("getJDBCMajorVersion : "+ metadata.getJDBCMajorVersion());
			System.out.println("getJDBCMinorVersion : "+ metadata.getJDBCMinorVersion());
			System.out.println("getSQLStateType : "+ metadata.getSQLStateType());
			System.out.println("locatorsUpdateCopy : "+ metadata.locatorsUpdateCopy());
			System.out.println("supportsStatementPooling : "+ metadata.supportsStatementPooling());
			System.out.println("getRowIdLifetime : "+ metadata.getRowIdLifetime());
//			System.out.println(" : "+ metadata.getSchemas(String catalog, String schemaPattern));
			System.out.println("supportsStoredFunctionsUsingCallSyntax : "+ metadata.supportsStoredFunctionsUsingCallSyntax());
			System.out.println("autoCommitFailureClosesAllResultSets : "+ metadata.autoCommitFailureClosesAllResultSets());
			System.out.println("getClientInfoProperties : "+ metadata.getClientInfoProperties());
//			System.out.println(" : "+ metadata.getFunctions());
//			System.out.println(" : "+ metadata.getFunctionColumns());
//			System.out.println(" : "+ metadata.getPseudoColumns());
//			System.out.println("generatedKeyAlwaysReturned : "+ metadata.generatedKeyAlwaysReturned());
			System.out.println("getMaxLogicalLobSize : "+ metadata.getMaxLogicalLobSize());
			System.out.println("Retrieves whether this database supports REF CURSOR : " +metadata.supportsRefCursors());
		} catch(Exception e) {
			e.printStackTrace();
			System.out.println(e);
		}
	}

}

 

 

으~ 오라클 – Call Stored Procedure from Java Code 하는중에 생긴 중대한 호환성 오류

제목은 영어지만 내용은 한국어로

http://viralpatel.net/blogs/java-passing-array-to-oracle-stored-procedure

좋은 샘플 발견해고 코드 수정해서 돌려봤는데…

아무리 해도 응답값이 ARRAY.lengh() == 빵트루

뭐가 잘못된건가 싶어서 할 수 있는 모든코드에 디버깅을 돌려봤지만…

오라클은 디버깅이 안되지…

 

이런경우가 오랜만이라 쓸데없이 디버깅 하느라 반나절을 날려먹었다.

Solution : http://stackoverflow.com/questions/14998299/oracle-array-filled-with-null-data-in-java

 

이걸 항상 명심해야하는데말이지

알 수도 없고 디버깅 해도 안되는 오류는… 블랙박스 라이브러리의 버전 문제다.
이 프로젝트에는 오라클 ojdbc14.jar을 쓰고 있었는데
ojdbc6.jar + orai18n 이걸로 교체 해 주니 해결됐다.
코드에는 문제가 없었던걸로…

자바 개발을 하다보면 오픈소스만 쓰다보니 모든걸 직접 디버깅하고 오류를 발견할 수 있으리라는 착각에 빠지게 된다. 라이브러리도 정 맘에안드는 부분은 소스 수정하고 jar 패키징 다시해서 쓰기도 하고 하니까… github forking 해서 쓰기도 하고

오라클이나 SAP 등등 상용툴과 마주하게 되면 다른 개발습관이 필요한데

 

Oracle 프로시저 – 오브젝트 어레이 선언해서 돌리기

테스트코드 짜다가 버리기 아까워서 저장.

 

타입선언

create or replace TYPE USER_OBJECT AS OBJECT
(
    V_USERNAME     VARCHAR2(20),
    V_PHONE      VARCHAR2(20),
    V_ADDRESS       VARCHAR2(100)
);

create or replace TYPE USER_OBJECT_ARRAY AS TABLE OF USER_OBJECT;

테이블

 CREATE TABLE USERTABLE 
   (	V_USERNAME VARCHAR2(20), 
	V_PHONE VARCHAR2(20), 
	V_ADDRESS VARCHAR2(100)
   )

 

 

그냥 실행문

DECLARE
V_CODE                 VARCHAR2(100);
V_MSG                  VARCHAR2(100);
v_CNT NUMBER(4) :=0 ;
v_userArr USER_OBJECT_ARRAY;
v_user USER_OBJECT;

BEGIN

v_userArr := USER_OBJECT_ARRAY(USER_OBJECT('김유저', '010-000-3333', '서울시 전체'), USER_OBJECT('최유저', '010-4444-4444', '경기도 전체'));

for i in 1..v_userArr.count loop
  dbms_output.put_line(v_userArr(i).V_USERNAME);
end loop;
  
END;

 

 

프로시저

create or replace PROCEDURE         MASS_USER_PROCEDURE 
(
 v_userArr          in USER_OBJECT_ARRAY,
 O_RESULR_CODE                        OUT VARCHAR2,
 O_RESULT_MESSAGE                         OUT VARCHAR2) 
 
IS

--V_USERNAME     VARCHAR2(20);
--V_PHONE      VARCHAR2(20);
--V_ADDRESS       VARCHAR2(100);
    
i BINARY_INTEGER := 0;

BEGIN

for i in 1..v_userArr.count loop
  dbms_output.put_line(v_userArr(i).V_USERNAME);
  insert into usertable (V_USERNAME, V_PHONE, V_ADDRESS) values (v_userArr(i).V_USERNAME, v_userArr(i).V_PHONE, v_userArr(i).V_ADDRESS); 
end loop;
commit;
   
END MASS_USER_PROCEDURE;

 

프로시저 호출코드

DECLARE
v_code                     VARCHAR2(100);
v_message                  VARCHAR2(100);
v_userArr USER_OBJECT_ARRAY;
v_user USER_OBJECT;

BEGIN

v_userArr := USER_OBJECT_ARRAY(USER_OBJECT('김유저', '0103333', '서울시 전체'), USER_OBJECT('최유저', '0104444', '경기도 전체'));

for i in 1..v_userArr.count loop
  MASS_USER_PROCEDURE(v_userArr, V_CODE, V_MSG);
  dbms_output.put_line(v_CODE);
end loop;
  
END;

 

 

 

 

제일 도움된 페이지 :

https://oracle-base.com/articles/8i/collections-8i