Stored Procedure가 성능 면에서는 일반 Query 보다 앞선 다는 걸 알면서도 선뜻 사용하기가 주저해진다. 익숙하지 않는 부분이 하나 일 것이고, 디버깅도 쉽지 않기 때문일 것이다.

뭐... 요즘처럼 JDBC 이외에 ORM 까지 사용하는 세상에 Stored Procedure는 정말 찬밥 이기 쉬운 듯 하다.

하지만... 장점도 있는 것이... DB dependent 한 Code를 Stored Procedure로 숨길 수도 있는데.. 이 부분은 Product를 개발하는 입장에서는 정말 매력적인 장점이 아닐까 생각 된다.

뭐.. 어쩌다가 요즘 혼자 개발하다가 갑자기 Stored Procedure를 쓸 일이 생기니 좀 당황 스러웠다.

생각해 보면 예전에 DBA가 SQL*PLUS에서 Stored Procedure를 어떻게 실행하는 지 물어 보기도 했으니.. 그리 부끄러워 할 일은 아닌 듯 하다.

일단 Stored Procedure를 실행 할려면 아래 처럼 하면 된다.

var rc refcursor;

execute ( ... , : rc);

print rc;

우리회사는 보통 Cursor를 제일 마지막에 사용하다 보니 위에 처럼 Output Cursor를 마지막에 넣어 주고... print 문으로 Cursor를 찍어 본다.

그리고 개발을 하다 보니 Stored Procedure가 LOOPING을 도는 것 같은 데 확인할 방법이 없다.

뭐.. 이럴 때는 Query를 확인 해야 하는 데 아래와 같이 CURSOR OPEN 하기 전에 Query를 찍으면 도움이 될 듯 하다.

dbms_output.put_line(p_sql);

근데.. 이걸 했는데도 Query가 콘솔에 찍히지 않아 왜 그런가 확인해 봤더니 아래 환경 변수를 ON 시켜 주어야 한다나..

SET SERVEROUTPUT ON

확인해 보니깐..
조건절을 잘못 넣어서 2억개가 넘는 ROW를 CURSOR에 넣고 있었다...-.-


어쩟든 기존에 개발 되어 있던 여러 Stored Procedure를 참조해서 필요한 Stored Procedure를 개발했는데.
참 어처구니 없는 것이... PL/SQL에는 문자열 split 함수가 없다.
인터넷을 뒤지고 다녔더니.. 다들 자기 들 만의 문자열 split 함수를 올려 놨다.
마침 Vinayak이 방에 놀러 왔길 래 사정 얘기를 했더니..
OAS에서 Cursor, Pipe를 이용해 구현한 함수와 사용 예제를 보여주어 덕분에 쉽게 해결 됐다.
다음에 또 stored procedure를 개발할 일이 생겼을 떄는 split 함수가 지원 되기를 기원한다.


'개발자세상 > Database관련' 카테고리의 다른 글

오라클 DB에서 테이블마다 용량 구하기  (0) 2013.08.10
Overlap 데이터 구하기  (0) 2013.08.04
오라클 실행계획 보기  (0) 2010.03.03
ORACLE 사용자 생성  (0) 2010.03.03
ORA-30557  (0) 2009.12.09
Posted by headiron
,

자바?

개발자세상 2011. 4. 1. 13:17
몇 일 전에 제임스 고슬링이 구글에 입사 했다는 뉴스가 눈에 띄더니,
오늘 REST 관련 자료를 찾다가 조대협씨가 MS에서 일한다는 내용이 눈에 띈다.

사실 제임스 고슬링이 ORACLE을 그만 둔지는 꽤 되었고, 생각해 보니 조대협씨가 MS 들어갔다는 얘기도 살짝 들었던 기억이 난다.

하지만 최근 ORACLE이 돌아가는 분위기를 보다보니 위 사실들이 더 충격적으로 다가오는 느낌이다.

많은 자바 개발자들이 SUN이 IBM에 인수되었어야 했다고 아쉬워한다.(그리고 했다.)
그리고 오라클이 SUN을 인수 했을 때 우려하던 일들이 서서히 나타나고 있다.

사실 SUN이 자바를 잘 디자인 하고 발전시켜 왔기에 지금과 같은 자바 부흥기가 왔다고 할 수 있는데,ORACLE은 그런 점을 기대하기에는 너무 상업적인 회사이다.

앞으로 어떤일이 벌어 질지는 모르겠다.

하지만 지금 상황으로는 예전 만큼이나 자바가 각광받기에는 조금 어려워 지지 않을까 생각된다.

그것만큼이나 걱정되는 건... 나 스스로 프로그래머라는 단어보다는 자바 개발자라는 단어가 더 익숙해 졌다는 사실이다.


'개발자세상' 카테고리의 다른 글

Hibernate interceptor  (0) 2015.05.20
Curl에서 SOAP API 사용하기  (0) 2014.05.07
Long Term Plan?  (0) 2011.02.19
이젠 모바일인가...  (2) 2010.12.05
Spring Security  (0) 2009.12.21
Posted by headiron
,

Long Term Plan?

개발자세상 2011. 2. 19. 10:40
Sales 측 요청으로 잠재 Client와 API 관련 검토 미팅을 하는데 ( Conference 로...^^ ) 고객이 API 관련 Long Term Plan을 물어 본다.

정팀장님이 계시니깐, 나야 따로 할 말이 없지만 그 얘기를 들으니 머리가 좀 띵하다.

우리 제폼의 API를 책임지고 있다는 놈이
앞으로 우리 시스템을 어떻게 발전시키겠다는 계획 없이 그냥 흘러가고 있다는 생각을 하니깐 골이 띵하다.

시키는 일만 하는 타성에 젖어, 내 제품을( 물론 내 개인 거는 아니지만 ) 어떤 방향으로 가져가겠다는 생각이나 포부도 없었구나 생각을 하니 많이 반성이 된다.

내 회사와 우리 제품에 자부심을 가지면서도 어떻게 가꾸어 나가겠다는 생각이 없는 건 큰 문제 인듯 하다.

내 인생 , 내 회사, 내 제품에 대한 긴 안목의 계획을 세워나가야 할 그런 시간이 온 듯 하다.

'개발자세상' 카테고리의 다른 글

Curl에서 SOAP API 사용하기  (0) 2014.05.07
자바?  (0) 2011.04.01
이젠 모바일인가...  (2) 2010.12.05
Spring Security  (0) 2009.12.21
ASP.NET 크레튜 강의 수강 소감  (0) 2009.12.15
Posted by headiron
,
주말에 뭔가 좀 해 볼까 했는데
PVT 일정이 잡히는 바람에 그냥 동네에 머물기로 했다.

대신 반스&노블스나 가서 책이나 좀 사기로 했다.
인터넷으로 검색해 보니 Target 있는 지역에 함께 있다.
살아 가다 보니 North Wales 지역이 생각보다는 살기 괜찮은 듯 싶다.

반스&노블스, Macy's 백화점, Cosco, Assi Mart 등.
관광서를 제외한 다른 상점 같은 것들은 많이 있는 듯 싶다.
( 관공서는 NorrisTown 지역에 많이 몰려 있는듯 )

여하튼 Web Service 관련 책 좀 사볼까 해서 Amazon에서 평점 괜찮은 걸로 2개를 고른다음에 가 보았다.

근데.. 이런.... 그 큰 서점에 컴퓨터 관련 책장은 달랑 하나.
그 중 반은 Window 관련 , 반은 아이폰/안드로이드...
자바 관련 책은...-.-

그래도 한참 벤처 바람 불때는 교보문고 같은데 한쪽을 자바 관련 책으로 도배를 했었는데.-.-
결국 미국도 모바일쪽으로 많이 넘어 가고 있는건가 싶다.

Amazon으로 볼때는 그래도 프로그래밍 관련 전문서적은 좀 많은 것 같았는데..

결국 나도 그런 부분을 조금씩 보면서 준비를 해야 하는 듯 싶다.

'개발자세상' 카테고리의 다른 글

자바?  (0) 2011.04.01
Long Term Plan?  (0) 2011.02.19
Spring Security  (0) 2009.12.21
ASP.NET 크레튜 강의 수강 소감  (0) 2009.12.15
티맥스 소식  (0) 2009.11.10
Posted by headiron
,
1. explain plan for
   select * from emp;

    select * from table(dbms_xplan.display);

2. explain plan
    set statement_id = 'stmt1' for
    select * from emp;

    select * from table(dbms_xplan.display('plan_table','stmt1','all'));
    select * from table(dbms_xplan.display('plan_table','stmt1','typical'));
    select * from table(dbms_xplan.display('plan_table','stmt1','basic'));

'개발자세상 > Database관련' 카테고리의 다른 글

Overlap 데이터 구하기  (0) 2013.08.04
Stored Procedure 개발 / 실행  (0) 2012.12.08
ORACLE 사용자 생성  (0) 2010.03.03
ORA-30557  (0) 2009.12.09
Oracle Table Column Rename  (0) 2009.10.28
Posted by headiron
,
CREATE USER 사용자명
IDENTIFIED BY 패스워드
DEFAULT TABLESPACE 테이블스페이스명
TEMPORARY TABLESPACE TEMP
PROFILE DEFAULT
ACCOUNT UNLOCK;

GRANT DBA,RESOURCES TO 사용자명;

ALTER USER 사용자명 DEFAULT ROLE ALL;

GRANT UNLIMITED TABLESPACE TO 사용자명;

'개발자세상 > Database관련' 카테고리의 다른 글

Stored Procedure 개발 / 실행  (0) 2012.12.08
오라클 실행계획 보기  (0) 2010.03.03
ORA-30557  (0) 2009.12.09
Oracle Table Column Rename  (0) 2009.10.28
오라클 Function Compile/ 생성시 Ora-00942 오류..  (1) 2009.06.22
Posted by headiron
,
백업 중 중간 경유지 역활을 하던 테스트 서버가 죽어
다른 서버를 경유해서 offsite 백업을 진행하게 script를 짜려고 하나다
키 기반 인증을 설정하려고 했더니

아뿔싸 그 내용을 테스트 서버에 있던 wiki에 정리 해 놨었다는...-.-

일단 시스템 운영 팀에 문의를 해서 아래와 같이 받았다.

Client측에서
shell> ssh-keygen -t rsa 실행
shell> cd ~/.ssh
shell> id_rsa.pub에 생성된 공용키 정보를 저장

Server측 (remote )에서
shell>> cd ~/.ssh
shell>> vi authorized_keys
shell>> Clicent측에서 생성된 공용키 정보를 authorized_keys 파일 끝에 추가한다.

주의 사항 
출처 : http://soul.tistory.com/37

서버에서 sshd.conf 파일을 수정해줍니다.

  vi /etc/ssh/sshd.conf

  sshd.conf 파일안에 AuthorizedKeysFile 항목이 주석처리가 되어있으면 주석해제를 해주고 위에서 별도의 이름으로 키파일을

    변경하였다면 임의로 지정한 파일명으로 변경해주면 됩니다.

   (예 - AuthorizedKeysFile      .ssh/test_keys)

 - sshd.conf 수정 후 sshd 서비스를 재시작 합니다.    service sshd restart   또는  /etc/init.d/sshd restart


ssh는 다른 사용자가 쓰기 권한을 갖을 수 있다면 키를 전송하지 않습니다.
예상컨데 .ssh/ 디렉토리를 user가 직접 생성했는데 이게 775(rwxrwxr-x) 로 생성됐을 것 같습니다.
.ssh/ 디렉토리는 700으로 .ssh/ 아래의 파일은 600으로 변경
authorized 파일을 생성할 경우에 644 ( rw-r--r-- ) 로 설정을 하여야 한다.
테스트 서버에서 작업 중에 664 ( rw-rw-r--)로 생성되었는데, 적용이 되지 않아 다른 서버와 비교후에 권한을 644로 바꾸니 바로 적용되었다.



Posted by headiron
,
WSDL2Java로 나온 Class들 전체를 javac로 실행하다 보니 out of memory가 발생한다.

구글링을 해보니 두가지 방법이 보인다.

1. javac Task에 fork="true" memoryMaximumSize="512M" 을 주는 방법
  ( fork를 기재 하지 않을 경우 memoryMaximumSize Option은 ignore 된다. )

2. javac Task에 compilerarg option을 준다.
    javac -help를 입력할 경우 javac 입력시 사용할 수 있는 Option이 나오게 되며 이 중 적절한 option을 입력하면 된다.
<javac srcdir="gen" destdir="gen-bin" debug="on" fork="true">
   
<compilerarg value="-J-Xmx512M" />
</javac>

   ( command prompt 내에서는 -J-Xmx를 입력할 경우 java stack size를 입력할 수 있는 걸로 나오는데 eclipse 의 ant plugin 에서는 해당 option이 먹지 않는걸로 나온다. )
참고 URL : http://stackoverflow.com/questions/16935/ants-javac-tasks-throws-stackoverflowexception
http://blog.paran.com/rabbitshin/6134979
Posted by headiron
,

Spring Security

개발자세상 2009. 12. 21. 19:22

B3 진행하면서 Spring 의 Remoting 호출을 지원하면서 해당 호출을 Login Base로 진행하기 위해서 Spring Security를 두가지 방식으로 지원하게 되었다.

하나는 Config 설정에 의한 , 다른 하나는 LDAP Base.

어차피 Spring Security의 로그인이 Filter Chain을 적용하는 것이기에 Multiple Filter Chain을 확인해 봤더니 Login Path를 통해서 Multiple Filter Chain을 지원하고 있었다.

우선 web.xml 을 변경하여야 한다.

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>springSecurityFilterChain</param-value>
        </init-param>
    </filter>

보통의 경우는 springSecurityFilterChain 만 선언하면 문제가 없는데
multiple 한 fileter chain을 명시적으로 Spring Security Config에 선언해 주어야 하기 때문에 반드시 targetBeanName을 선언하여 value에는 Spring Security 설정에서 사용한 FilterChain Bean Name을 선언해 주어야 한다.

Spring Security 내부의 Filter Chain이 아닌 명시적인 Filter Chain을 사용하여야 하기 때문에 사용하는 방식에 맞추어 Filter Chain Config를 선언하여야 한다.

    <bean id="springSecurityFilterChain" class="org.springframework.security.util.FilterChainProxy">
        <s:filter-chain-map path-type="ant">
            <s:filter-chain pattern="/batchProcessService/**" filters="httpSessionContextIntegrationFilter,digestProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
            <s:filter-chain pattern="/approvalProcessService/**" filters="httpSessionContextIntegrationFilter,digestProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor" />
            <s:filter-chain pattern="/**" filters="ldapHttpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,ldapExceptionTranslationFilter,sessionFixationProtectionFilter,ldapFilterInvocationInterceptor"/>
        </s:filter-chain-map>
    </bean>

web.xml 에서 선언했던 filterChain을 위와 같이 설정한다.
filter-chain의 pattern attribute에 선언된 URL에 맞추어 각각 선언된 Filter Chain이 적용이 된다.

위의 경우
/approvalProcessService/** 및 /batchProcessService/** URL은는"httpSessionContextIntegrationFilter,digestProcessingFilter,exceptionTranslationFilter,filterSecurityInterceptor" Filter Chain이
그 이외의 URL들은
"ldapHttpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter,anonymousProcessingFilter,ldapExceptionTranslationFilter,sessionFixationProtectionFilter,ldapFilterInvocationInterceptor"
Filter Chain이 적용되게 된다.

LDAP 을 위해서는 아래의 Bean을 명시적으로 선언하였다.
물론 다른 것에 대해서도 해야 겠지만.^^

    <bean id="ldapHttpSessionContextIntegrationFilter" class="org.springframework.security.context.HttpSessionContextIntegrationFilter" />

    <bean id="logoutFilter" class="org.springframework.security.ui.logout.LogoutFilter">
        <constructor-arg value="로그아웃 후 Redirect될 페이지 URL" />
            <constructor-arg>
                <list>
                    <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler" />
                </list>
            </constructor-arg>
        <property name="filterProcessesUrl" value="/j_spring_security_logout" />
         ( Logout Process Path URL )
    </bean>

    <bean id="authenticationProcessingFilter"    class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
        <property name="authenticationManager"         ref="ldapAuthenticationManager" />
        <property name="authenticationFailureUrl"     value="/ldapLogin.zul?error=1" />
        <property name="defaultTargetUrl"            value="로그인 시 기본 Redirect 페이지 URL" />
        <property name="filterProcessesUrl"            value="/j_spring_security_check" />
    </bean>

    <bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter" />

    <bean id="anonymousProcessingFilter" class="org.springframework.security.providers.anonymous.AnonymousProcessingFilter">
        <property name="key" value="doesNotMatter" />
        <property name="userAttribute" value="roleAnonymous, ROLE_ANONYMOUS" />
    </bean>           

    <bean id="ldapExceptionTranslationFilter" class="org.springframework.security.ui.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint">
            <bean class="org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint">
                <property name="loginFormUrl" value="로그인 입력화면 URL" />

            </bean>
        </property>
        <property name="accessDeniedHandler">
            <bean class="org.springframework.security.ui.AccessDeniedHandlerImpl">
            </bean>
        </property>
    </bean>

    <bean id="sessionFixationProtectionFilter" class="org.springframework.security.ui.SessionFixationProtectionFilter" />

    <bean id="ldapFilterInvocationInterceptor" class="org.springframework.security.intercept.web.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="ldapAuthenticationManager" />
        <property name="accessDecisionManager" ref="ldapAccessDecisionManager" />
        <property name="objectDefinitionSource">
            <s:filter-invocation-definition-source>
                <s:intercept-url pattern="/siteList/**" access="IS_AUTHENTICATED_REMEMBERED"/>
                <s:intercept-url pattern="/**"             access="IS_AUTHENTICATED_ANONYMOUSLY"/>
            </s:filter-invocation-definition-source>                       
        </property>
    </bean>

    <bean id="secondLdapProvider"
        class="org.springframework.security.providers.ldap.LdapAuthenticationProvider">
        <s:custom-authentication-provider />
        <constructor-arg>
            <bean               class="org.springframework.security.providers.ldap.authenticator.BindAuthenticator">
                <constructor-arg ref="contextSource" />
                <property name="userSearch">
                    <bean id="userSearch"                        class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
                        <constructor-arg index="0" value="" />
                        <constructor-arg index="1" value="(&amp;(sAMAccountName={0})(objectclass=user))" />                       
                    </bean>
                </property>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.security.ldap.populator.DefaultLdapAuthoritiesPopulator">
                <constructor-arg ref="contextSource" />
                <constructor-arg value="" />
                <property name="groupSearchFilter" value="(&amp;(member={0})(|(cn=B3 Reader)(cn=B3 Approval)))" />               
                <property name="rolePrefix" value="ROLE_" />
                <property name="searchSubtree" value="true" />
                <property name="convertToUpperCase" value="false" />
            </bean>
        </constructor-arg>
    </bean>

'개발자세상' 카테고리의 다른 글

Long Term Plan?  (0) 2011.02.19
이젠 모바일인가...  (2) 2010.12.05
ASP.NET 크레튜 강의 수강 소감  (0) 2009.12.15
티맥스 소식  (0) 2009.11.10
강사의 조건  (1) 2009.10.22
Posted by headiron
,
지난 달에 C#을 들으려 했었는데 신청을 잘 못해서 ASP.NET 강의를 듣게 됐다.

뭐... C#다음 강좌로 ASP.NET도 들을려고 했었으니깐 순서만 한번 바뀌었다고나 할까.

들으면서 느낀것은 MS 진영이고 Java 진영이고 서로가 서로에게 긍정적인 영향을 준다고나 할까.

ADO.NET을 보면 JDBC적인 면이 보이고 반대로 JSF를 보면 ASP.NET의 객체 모델이 보이고,
서로에 대해서 자신이 우월성을 얘기하려 노력하지만
결국은 서로의 장점을 취해 가며 발전해 가는 모습을 보면
선의의 경쟁자라 불러도 좋을 듯 싶다.

별 경쟁 없이 있던 브라우저 시장도 Firefox가 힘을 받고 크롭 같은 브라우져가 등장하면서 다시 발전해 가는 것을 보면 독과점의 폐해는 실로 심각하다 할 수 있겠다.

뭐... 어쩃든 다음에 C# 강좌를 마무리로 들어주면 MS 관련 문제가 발생해도 어느정도는 대체할 수 있지 않을까 생각된다.

그리고 크레듀 강좌 들으면서 .... 테크빌에서 했떤 일들이 자꾸 떠올랐다.
그때 그래도 괜찮은 기능들을 많이 많들었다는 생각이 들고
또 한편으로는 내가 100% 소화 해 내지 못했던 것들에 대한 아쉬움도 들고 했다.
그리고 그쪽을 떠난 지도 6년 가까이 되는데 아직도 그떄 일을 생각하는 걸 보면
나에게 많은 아쉬움도 남아 있는 듯 하다.

'개발자세상' 카테고리의 다른 글

이젠 모바일인가...  (2) 2010.12.05
Spring Security  (0) 2009.12.21
티맥스 소식  (0) 2009.11.10
강사의 조건  (1) 2009.10.22
Streaming Protocol  (0) 2009.10.06
Posted by headiron
,