사용하고 있는 오라클 시스템의 버젼을 확인 하는 방법


다음의 쿼리를 수행하면 버전을 확인 할 수 있다.

SELECT * FROM V$VERSION;

수행 결과는 다음과 같이 출력된다.


저작자 표시

Write your message and submit

오라클 문자컬럼에서 숫자타입이 아닌 문자가 존재하는 컬럼 구하기


  프로젝트 진행 중에 VARCHAR2 컬럼에 숫자값을 입력하는 경우가 존재하는데 숫자가 아닌 문자가 들어간 DATA를 걸러내야 할 때가 있다. 다음과 같이 하면 양수의 숫자만 들어간 컬럼만 찾아낼 수 있다. 
  오라클 함수중에 REGEXP_INSTR(...)이 있는데 정규식을 이용해서 해당 컬럼의 원하는 정규식 pattern의 자리수를 얻어오는 것이다.

SELECT COL FROM (
    SELECT '12.0' AS COL FROM DUAL
    UNION ALL SELECT '52/0' FROM DUAL
    UNION ALL SELECT '52U0' FROM DUAL
    UNION ALL SELECT '%2U0' FROM DUAL
) T 
WHERE  REGEXP_INSTR(T.COL , '[^{.1234567890}]') <= 0

수행 결과는 다음과 같다.

COL
----
12.0

저작자 표시

Write your message and submit

ORA-01009:필수 매개변수가 없습니다.


  회사 업무처리중에 오라클 오류메시지를 만났습니다. ‘ORA-01009’! 필수 매개변수가 없다고 하는데 쿼리에는 특별히 문제가 없었습니다. 구글신에게 물어봤습니다. 구글신은 쿼리에 주석을 달때 이 런문제가 생긴수 있다는 말이 있었습니다. 주석 중에 /* */ 사이에 주석 내용을 입력할 때 한칸씩 떼어야 한다던가 -- 문제 다음에 한칸을 반드시 떼어야 한다는 내용이었습니다. 다음과 같이 말이죠.
/* 주석내용 */
-- 주석 내용
그래서 살펴봤더니 주석이 존재하고 있었습니다. 그런데 -- 다음에 한칸이 떨어진 정상적인 상태였습니다. 그래서 아주 주석을 삭제하고 처리해 봤지만 마찬가지로 오류가 발생했습니다. 구글신은 그 다음의 TIP을 주지 못했습니다. 무려 5시간 끝에 해결했습니다.

쿼리는 다음과 같은 형태였습니다.

WITH AAA AS (
   SELECT AAA FROM TABLE000
)
SELECT ... FROM AAA, BBB
WHERE ...

이렇게 된 쿼리를 JAVA에서 StringBuffer로 append 처리해서 쿼리 스트링을 구성하고 있었습니다. 해결은 다음과 같습니다.

SELECT * FROM (

   WITH AAA AS (
       SELECT AAA FROM TABLE000
   )
   SELECT ... FROM AAA, BBB
   WHERE ...

)

이렇게 WITH절이 가장 밖에 노출 되었던 형태를 한번 더 감싸서 SELECT 문을 단순 변경 했습니다. 그러고 나니 정상적으로 수행되었습니다.
참고로 Local에서 테스트 할 때는 문제 없었던 내용이었으나 Real 서버에 deploy한 뒤 발생한 문제였습니다. Local 환경과 Real 서버 환경은 다음과 같습니다.

Local :  Windows7, jdk 1.4.2 16, Tomcat 5.0
Real :  SonOs 5.9, jdk 1.4.2 16, Jeus 42

정말 이럴 때는 어떻게 처리해야 할 지... 이글 참고하시어 만일 이런일 이 생기셨을 때 저처럼 5시간 넘게 시달리지 마시길 빕니다.
저작자 표시
  • 혼자 주말근무 나와서 동일 메세지로 끙끙대던중
    이글이 도움이 되었습니다

    쿼리는 동일 방식을 사용하지만(유지보수를 위해서라나)
    전 주석만 고쳐서 해결이 된 케이스네요

    감사합니다

  • 도움이 되셨다니 기쁘네요 ^^

Write your message and submit

오라클 사용자 예외처리 사용 방법


  PL-SQL 작성시 오라클 저장함수 RAISE_APPLICATION_ERROR를 사용하여 사용자 정의 예외를 다룰 수 있다. 우리히가 흔히 보는 'ORA-XXXXX'이런 코드를 작성해서 메시지와 함께 발생시킬 수 있다. 숫자 범위는 -20000부터 -20999의 범위 내에서 가능하다.

CREATE OR REPLACE FUNCTION FN_GET_MACHINE_NO(
       l_cd IN VARCHAR2
      ,m_cd IN VARCHAR2
      ,s_cd IN VARCHAR2
) RETURN VARCHAR IS  retval VARCHAR2(14);

  seqNextVal VARCHAR(7);
  lCdVal     VARCHAR(1);
  mCdVal     VARCHAR(2);
  sCdVal     VARCHAR(3);
  INPUT_ERR  EXCEPTION;
  OUTPUT_ERR EXCEPTION;

BEGIN
     seqNextVal := 0;
     lCdVal := TRIM(l_cd);
     mCdVal := TRIM(m_cd);
     sCdVal := TRIM(s_cd);
  
     BEGIN 
           -- 20100823 LCS 수정 : 소분류가 NULL이면 '99'기본값 설정.
           IF(sCdVal IS NULL) THEN
               sCdVal := '99';
           END IF;
         
           IF( lCdVal IS NULL OR mCdVal IS NULL ) THEN
               RAISE INPUT_ERR;
           ELSE
               SELECT SUBSTR( LPAD(DQ_DQMACHN_INDEX.NEXTVAL , 12, '0') , 6, 7)
                 INTO seqNextVal
               FROM DUAL  ;
     
               retval := lCdVal || mCdVal || sCdVal || TO_CHAR(SYSDATE, 'YY') || seqNextVal  ;
           END IF;
           
           IF LENGTH(retval) <> 14 THEN
              RAISE OUTPUT_ERR;
           END IF;
     
     EXCEPTION
     
         WHEN INPUT_ERR THEN

           IF( lCdVal IS NULL ) THEN
                -- 대분류코드값이 없을 때 Exception 발생
                RAISE_APPLICATION_ERROR(-20998,'전달된 파라미터(분류코드)에 문제가 있습니다(대분류 코드값이 없습니다.)');
           ELSIF( lCdVal IS NULL OR mCdVal IS NULL ) THEN
                -- 중분류코드값이 없을 때 Exception 발생
                RAISE_APPLICATION_ERROR(-20998,'전달된 파라미터(분류코드)에 문제가 있습니다(중분류 코드값이 없습니다.)');
           END IF;
           
         WHEN OUTPUT_ERR THEN
           --DBMS_OUTPUT.PUT_LINE('생성된 기기관리번호('||retval||')는 14자리가 아닙니다.');
           RAISE_APPLICATION_ERROR(-20999,'생성된 기기관리번호('||retval||')는 14자리가 아닙니다.');
         WHEN NO_DATA_FOUND THEN
           NULL;
         WHEN OTHERS THEN
           NULL;
     END;
     
RETURN retval;

END FN_GET_MACHINE_NO;

  위 예제에서 처럼 최상단에 exception을 선언하고 중간에 RAISE를 사용해서 특정 조건에 만족하면 Exception을 발생시키고 하단에 RAISE_APPLLICATION_ERROR(...) 함수를 사용해서 구체적인 에러코드와 메시지를 구성해서 발생시키면 된다.
  이렇게 사용하게되면 Application단에서 exception 다루는 방법 그대로 잡아낼 수 있다. ORA-20999 Exception이 발생하게 된다.
저작자 표시

Write your message and submit

Oracle 유용 구분 정리 해석내용 - PARTITION BY, START WITH...CONNECT BY PRIOR


이전에 유용 구분이라고 작성한 내용을 해석해 보겠다.
우선 기본이 되는 table이 있어야 하는데 없으니까 view를 생성하는 부분이 다음과 같다. 

WITH TVIEW AS (
    SELECT 'a' AS ac , '1a' AS acv FROM dual UNION ALL
    SELECT 'a' AS ac , '3a' AS acv FROM dual UNION ALL
    SELECT 'e' AS ac , '2e' AS acv FROM dual UNION ALL
    SELECT 'a' AS ac , '4a' AS acv FROM dual UNION ALL
    SELECT 'b' AS ac , '1b' AS acv FROM dual UNION ALL
    SELECT 'c' AS ac , '1c' AS acv FROM dual UNION ALL
    SELECT 'g' AS ac , '2g' AS acv FROM dual UNION ALL
    SELECT 'c' AS ac , '2c' AS acv FROM dual UNION ALL
    SELECT 'c' AS ac , '3c' AS acv FROM dual UNION ALL
    SELECT 'a' AS ac , '2a' AS acv FROM dual UNION ALL        
    SELECT 'd' AS ac , '1d' AS acv FROM dual UNION ALL
    SELECT 'e' AS ac , '1e' AS acv FROM dual UNION ALL    
    SELECT 'f' AS ac , '1f' AS acv FROM dual UNION ALL
    SELECT 'g' AS ac , '1g' AS acv FROM dual UNION ALL
    SELECT 'g' AS ac , '3g' AS acv FROM dual UNION ALL
    SELECT 'h' AS ac , '1h' AS acv FROM dual UNION ALL
    SELECT 'h' AS ac , '2h' AS acv FROM dual UNION ALL
    SELECT 'i' AS ac , '1i' AS acv FROM dual
)

이 내용은 다음 과같다.


이 내용을 다음 쿼리를 적용하면 

SELECT ac ,MAX(SYS_CONNECT_BY_PATH (acv, '|')) AS acvl
FROM (
        SELECT 
                ac, acv
                ,(ROW_NUMBER () OVER (PARTITION BY ac  ORDER BY ac, acv  )) RNUM    -- (1)
        FROM TVIEW
) START WITH RNUM = 1 CONNECT BY PRIOR RNUM = (RNUM - 1) 
AND PRIOR AC = AC
GROUP BY AC

다음과 같은 결과를 얻을 수 있다.


각 AC 값을 그룹으로 하는 내용들을 하나의 row를 사용해서 string으로 묶되 정렬된 그리고 구분자를 포한 string을 만드는 것이다. 이 내용이 프로젝트 참여시 간간히 필요할 때가 있어서 작성해 놓았다. 이제 Query의 부분을 진행해 보겠다.

기본 VIEW 형태에서 (1) 부분만을 적용했을 때는 다음과 같은 결과를 얻을 수 있다.


각 그룹 내에서의 ROW_NUMBER가 적용 되었있는 상태다. 물론 그룹내에서 sorting 되어진 상태에서 row_number가 적용된 것이다. PARTITION BY ac  ORDER BY ac, acv 구문을 통해서 ac를 그룹으로 내부에서 order by 적용되고 ROW_NUMBER () OVER ( ...) 구분을 통해서 그룹 내부에서 정렬된 결과로 row_number()가 적용된 것이다.

다음으로 START WITH RNUM = 1 CONNECT BY PRIOR RNUM = (RNUM - 1)  구분을 통해서 최종 형태를 얻어 내는 것이다. AC항목의 하나의 그룹단위로 RNUM이 1인 것부터 처리된다. 
SYS_CONNECT_BY_PATH( column, char )
SYS_CONNECT_BY_PATH(column, char) 함수는 계층적 쿼리(계층구조)에서만 유효하며, column의 절대 경로를 char로 지정한 문자로 분리하여 반환한다.

여기서 참고내용으로 CONNECTED BY 구분을 사용하게 되면 HASH_JOIN이 발생하는데 여기서 오류가 발생할 때도 있다. 이는 예전 글에 정리된 것을 참조하기 바란다. 이 오류를 경험한 것은 9i를 사용할 때 였고 이 후 버전에서 해결이 되었는지는 모르겠다.

Write your message and submit

Oracle 유용 구분 정리 - PARTITION BY, START WITH...CONNECT BY PRIOR


아래와 같은 임시 테이블(임시VIEW)의 정보를 하나의 ac에 대해서 속해있는 acv 값을 하나의 string로 나열하기.

WITH TVIEW AS (
    SELECT 'a' AS ac , '1a' AS acv FROM dual UNION ALL
    SELECT 'a' AS ac , '3a' AS acv FROM dual UNION ALL
    SELECT 'e' AS ac , '2e' AS acv FROM dual UNION ALL
    SELECT 'a' AS ac , '4a' AS acv FROM dual UNION ALL
    SELECT 'b' AS ac , '1b' AS acv FROM dual UNION ALL
    SELECT 'c' AS ac , '1c' AS acv FROM dual UNION ALL
    SELECT 'g' AS ac , '2g' AS acv FROM dual UNION ALL
    SELECT 'c' AS ac , '2c' AS acv FROM dual UNION ALL
    SELECT 'c' AS ac , '3c' AS acv FROM dual UNION ALL
    SELECT 'a' AS ac , '2a' AS acv FROM dual UNION ALL       
    SELECT 'd' AS ac , '1d' AS acv FROM dual UNION ALL
    SELECT 'e' AS ac , '1e' AS acv FROM dual UNION ALL   
    SELECT 'f' AS ac , '1f' AS acv FROM dual UNION ALL
    SELECT 'g' AS ac , '1g' AS acv FROM dual UNION ALL
    SELECT 'g' AS ac , '3g' AS acv FROM dual UNION ALL
    SELECT 'h' AS ac , '1h' AS acv FROM dual UNION ALL
    SELECT 'h' AS ac , '2h' AS acv FROM dual UNION ALL
    SELECT 'i' AS ac , '1i' AS acv FROM dual
)

예로 다음과 같이 결과를 만들기.

ac  acvl
=== ==============================
a   |1a|2a|3a|4a
b   |1b
c   |1c|2c|3c
...

다음과 같이 쿼리를 작성하면 된다.

SELECT ac ,MAX(SYS_CONNECT_BY_PATH (acv, '|')) AS acvl
FROM (
        SELECT
                ac, acv
                ,(ROW_NUMBER () OVER (PARTITION BY ac  ORDER BY ac, acv  )) RNUM
        FROM TVIEW
) START WITH RNUM = 1 CONNECT BY PRIOR RNUM = (RNUM - 1)
AND PRIOR AC = AC
GROUP BY AC

설명 및 테스트 결과 설명은 다음 글에서 ...

Write your message and submit

오라클 프로그램에서 한글 깨짐 현상 바로 잡기.



레지스트리에서 오라클 관련해서 NLS_LANG 속성이 3다음과 같이 3개가 존재합니다.

HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ALL_HOMES\ID0
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0

위의 모든 NLS_LANG 속성을 모두 KOREAN_KOREA.KO16KSC5601 로 변경하면 됩니다.
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ALL_HOMES\ID0
        NLS_LANG = KOREAN_KOREA.KO16KSC5601
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
        NLS_LANG = KOREAN_KOREA.KO16KSC5601
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0
        NLS_LANG = KOREAN_KOREA.KO16KSC5601

Write your message and submit

java.sql.SQLException: ORA-00600: internal error code, arguments: [qesmmCValStat4], [3], [1], [], [], [], [], []


프로젝트 진행중에 아주 난해하고 처음 보는 오류가 발샣 했다.

java.sql.SQLException: ORA-00600: internal error code, arguments: [qesmmCValStat4], [3], [1], [], [], [], [], []

검색을 해도 자료가 거의 없다. 그래서 회사 서버 관리 쪽에 문의 해서 알아 낸 결론은 오라클 오류란다.
그런데 이 건에 대한 patch 도 없다고 한다. 그래서 이 오류가 발생하지 않게 우회 하는 방법을 받았다.
쿠리 수행 전에

ALTER SESSION SET HASH_JOIN_ENABLED=FALSE;

을 수행한다. HASH_JOIN 을 막는 것이다. 아무튼 다행이다. 해결 되서. ^^

Write your message and submit

DB 모델링의 이슈


  • Entity Type의 병합 기준
  • Entity Subtype 관리 방안
  • Code 관리 방안
  • 집계 Entity Type 운용 방안
  • Index (index, primary index(key) 등...) 관리 방안
  • Relationship의 물리적 구현
  • RI(Referential Integrity) 운용 방안
  • 논리모델과 물리 모델과의 차이 파악과 관리 방안

Write your message and submit

Relationship에 관하여


    Relationship은 두 엔티티 타입 간의 관계를 표현하는데눈 양방향으로 표시. 관계를 표시하는 방법은 카디널리티(cardinality)와 옵셔널리티(optionality)가 사용
    
    cardinality
        엔티티 인스턴스가 다른 엔티티 타입의 엔티티 인스턴스와 맺을 수 있는 릴레이션쉽 인스턴스의 수효
    optionality
        엔티티 인스턴스가 다른 엔티티 타입의 엔티티 인스턴스와 맺어야 하는 관계가 필수인지 선택인지 표시

카디널리티와 옵셔널리티

카디널리티와 옵셔널리티

엔티티간 단방향

엔티티간 단방향 표시 (사용안함)

엔티티간 양방향

엔티티간 양방향 표시 (양방향으로 표시)


'Programming > Database' 카테고리의 다른 글

DB 모델링의 이슈  (0) 2008/01/03
Relationship에 관하여  (0) 2008/01/03
Entity에 관하여  (0) 2008/01/03
항목의 누적 data를 출력하는 query  (0) 2007/11/16

Write your message and submit