'it/db'에 해당되는 글 20건
OCILib를 사용하는 경우 필수 파일
오라클 테이블의 레코드 사이즈 계산을 쉽게하자
오라클 DB 테이블의 레코드 사이즈 계산을 할 필요가 있었다.
주요 소스 내용은 아래와 같다.
<head> <title>테이블 레코드 계산</title> <script src="http://code.jquery.com/jquery-1.5.min.js" type="text/javascript" charset="utf-8"></script> <script> /* 계산 공식 출처 http://epoonet.egloos.com/4479971 */ var pTable = [ { type: "char", calc:function(n){ return n; }}, { type: "varchar2", calc:function(n){ return n; }}, { type: "nchar", calc:function(n){ return 2 * n; }}, { type: "nvarchar2",calc:function(n){ return 2 * n; }}, { type: "number", calc:function(n){ return 1+ Math.ceil(n/2); }}, { type: "date", calc:function(n){ return 7; }}, { type: "raw", calc:function(n){ return n; }}, { type: "long", calc:function(n){ return n; }}, { type: "long raw", calc:function(n){ return n; }}, { type: "bfile", calc:function(n){ return 530; }}, { type: "rowid", calc:function(n){ return 6; }}, { type: "timestamp",calc:function(n){ return 13; }} ]; $(document).ready( function(){ $("#DoIt").click(function() { var resultText = ""; var inputText = $("textarea#src").val().toLowerCase().split("\n"); var lineString; var size =0, sum =0; var buf; for(var i=0; i<inputText.length; i++) { size = 0; if ( lineString=$.trim(inputText[i]) ) { for(var j=0; j<pTable.length; j++) { if ( lineString.substr(0, pTable[j].type.length) == pTable[j].type ) { try { size = Number(lineString.split("(")[1].split(")")[0]); } catch (e) { size = 0; } size = pTable[j].calc(size); break; } } } sum += size; resultText += lineString + " : " + size + "<br/>"; } resultText += "<br/><b>sum: " + sum + "</b>"; $("#result").html( resultText ); }); }); </script> <style type="text/css"> * { font-size:12px; font-family:맑은고딕 } </style> </head> <body> <textarea id="src" rows="20" cols="80"></textarea> <br/> <input type="button" value="Do It!" id="DoIt"> <br/> <br/> <span id="result"></span>
직접 실행을 위한 URL은 아래와 같다.
오라클 Plan 정보 보는 방법
보통 set autotrace on 명령으로 plan 정보를 보는데, 회사의 DBA가 추천한 방법이 있어서 기록을 남긴다.
1. 사용자 계정으로 DB 접속 ( 시스템 계정의 경우 불필요한 쿼리까지 포함됨 )
$ sqlplus system/
2. 쿼리 실행
SQL> alter session set sql_trace = true;
SQL> 쿼리실행 ( 복수의 쿼리 가능 )
SQL> alter session set sql_trace = false;
( udump 생성을 위해 필수 )
3. 결과 확인
$ cd $ORACLE_BASE
$ cd ./admin/DB명/udump
$ ls –ltr
( 가장 최근 파일 확인 )
$ tkprof 파일명.trc tt.txt sys=no;
( Trace 파일을 사람이 해석 가능 하도록 변환 )
$ cat tt.txt
오라클에서 조회한 결과를 Text 파일로 저장하기
오라클에서 다른 계정으로 데이터 마이그레이션 방법
Oracle Bulk Loader
Oracle Bulk Loader를 사용한다.
Loader를 사용하기 위해서는 컨트롤 파일과, 데이터 파일이 필요하다.
컨트롤 파일은 데이터 파일 정보와 테이블 정보를 가지고 있고,
데이터 파일은 DB에 넣고자 하는 데이터 목록을 가지고 있다.
1. 테이블 생성
NAME CHAR(20),
SCORE NUM(5),
UPDATE DATE );
2. 컨트롤 파일 생성
LOAD DATA
INFILE test.dat
INTO TABLE TEST_TBL
FIELDS TERMINATED BY ','
(NAME, SCORE, UPDATE SYSDATE)
USER1,70
USER2,80
USER3,90
USER4,100
4. 로더 실행
보다 상세한 사용법은 아래 링크를 참고 하세요
http://infolab.stanford.edu/~ullman/fcdb/oracle/or-load.html
http://www.orafaq.com/wiki/SQL*Loader_FAQ
Oracle import / export
Export
* 사용자 지정
* 테이블 지정
* 테이블 조건 지정
Import
* 사용자 지정
* 테이블 지정
* 테이블 조건 지정
테이블 조건 별로 Insert를 할 수가 없다.
ignore=y 옵션을 주면 에러가 발생해도 계속 진행한다.
-> DB오류가 발생하면 해당 레코드는 Insert 하지 않는다. (PK가 중복등..)
Pro*c를 이용한 오라클 PL/SQL function 호출
Proc*c를 이용해 Sub Program(Procedure or Function)을 호출 하는 방법에 대해 설명한다.
자료를 찾아보면 대부분의 샘플 코드가 Procedure 로만 되어 있다.
여기서는 Function을 호출 해 보기로 한다.
사실 호출 방법은 거의 비슷 하다.
- 컴파일 방법
PL/SQL 구문을 사용하기 때문에 proc 컴파일 옵션을 주어야 한다.
그런데, 컴파일 옵션을 주면 다른 Pro*c 구문에서 컴파일이 안되는 일이 발생을 한다.
따라서, PL/SQL 구문을 사용하는 소스는 별도 .pc 파일로 때어 내어서 별도 컴파일을 해야한다.
여기서 기존 컴파일 방법과 다른 부분은 "SQLCHECK=SEMANTICS" 옵션이 추가된 것과,
userid 옵션이 추가된 것이다.
userid 옵션에는 오라클 로긴을 위한 ID와 Password를 넣어 준다.
- 샘플 소스
/** @file sub.pc * @brief Remote Function Call * @author newtype * @date 2009-04-10 */ #ifndef _SUB_PC_ #define _SUB_PC_ #include "common.h" EXEC SQL INCLUDE SQLCA; /** @brief 오라클 Function을 호출 한다. * @param in [IN] 오라클 Fucntion Parameter * @param out [OUT] 오라클 Fucntion Return 값을 반환 * @return 0 정상처리 * @return 그외 오라클 에러 코드 * @remarks 참고 사항 * @warning 주의 사항 */ int CallOracleFunction(char* in, char* out) { EXEC SQL BEGIN DECLARE SECTION; char szOut[MAX_BUF] = ""; EXEC SQL END DECLARE SECTION; EXEC SQL EXECUTE BEGIN :szOut := ORA_SAMPLE_FUNC( in ); IF szOut = 'newtype' THEN strcpy( out, szOut) ; COMMIT; ELSE strcpy( out, 'newtype.pe.kr'); ROLLBACK; END IF; END; END-EXEC; return nErrCode; } #endif
ORA-01002 fetch out of sequence
ORA-01002 fetch out of sequence 는 여러 경우에 발생을 한다.
그중 한가지에 대한 오류 발생 사례 이다.
DB Link로 Remote 테이블을 참조 하고 있는 프로세스가 작업을 수행하고 있는 상태에서,
Remote DB가 Shutdown 되는 경우 위 에러가 발생 한다.
Remote DB가 Start되고 새로운 세션을 맺어야 프로세스가 정상 동작을 한다.
세션을 유지한 상태에서 Remote DB가 Start 되어도 위 에러가 계속 발생한다.
말이 어렵다 테스트 해보자.
1. ORA TNS에 RemoteDB를 추가한다.
2. DB 링크를 생성한다.
CREATE SYNONYM test_proc FOR test_proc_table@test_link
SELECT * FROM test_proc
3. 데이터를 삽입한다.
insert into test_proc values ( 2, 1 );
~~~~~~
insert into test_proc values ( 33, 1 );
insert into test_proc values ( 44, 1 );
4. 테스트 프로그램을 작성한다.
#include <stdio.h> EXEC SQL INCLUDE SQLCA; #define MAX_ARRAY_SIZE 10 int main() { int n; EXEC SQL BEGIN DECLARE SECTION; int hSEQ; char hOracleUser[20] = "localDBid"; char hOraclePwd[20] = "localDBpwd"; EXEC SQL END DECLARE SECTION; EXEC SQL CONNECT :hOracleUser IDENTIFIED BY :hOraclePwd; if(sqlca.sqlcode !=0) { printf( "login fail\n"); return 0; } for (n=0; n<10; n++) { printf( "start of job\n"); EXEC SQL DECLARE CUR_TEST_PROC CURSOR FOR SELECT SEQ FROM TEST_PROC; EXEC SQL OPEN CUR_TEST_PROC; while(1) { EXEC SQL FETCH CUR_TEST_PROC INTO :hSEQ; sleep(3); if(sqlca.sqlcode != 0) { if(sqlca.sqlcode == 1403) { printf( "data not found\n"); break; } else { printf( "fetch Error [%20s]\n" , sqlca.sqlerrm.sqlerrmc); break; } } printf("fetch [%d]\n", hSEQ ); } EXEC SQL CLOSE CUR_TEST_PROC; printf( "end of job\n"); } /* for */ return 0; }
$ proc iname=t.pc
$ cc -o t t.c -L/home/oracle/app/oracle/product/8.1.7/lib -lclntsh -R/home/oracle/app/oracle/product/8.1.7/lib
5. 프로세스 구동
6. Remote DB Shutdown
7. 에러 확인
이거 원인을 파악하려고, 오늘 하루를 다 보냈다. ㅡ.ㅡ
참고