C++, C# 및 SQL을 아신다면 이해에 큰 도움이 됩니다.

보안은 다차원적인 문제입니다. 어디에서나 보안상 위험이 발생할 수 있습니다. 사용자가 오류 처리 코드를 작성하거나 너무 많은 권한을 제공하는 경우, 서버에서 실행하고 있는 서비스가 무엇인지 잊어 버리는 경우, 모든 사용자 입력을 허용하는 경우 등이 있습니다. 그 밖에도 여러 가지 경우가 있습니다. 다음과 같은 안전한 네트워크 전략에 대한 10가지 주의 사항에 따라 시스템, 네트워크, 코드를 순조롭게 보호할 수 있습니다.

간이 목차
1. 사용자 입력 신뢰의 위험성
2. 버퍼 오버런 방지
3. 사이트 간 스크립팅 방지
4. sa 사용 권한 불필요
5. Crypto 코드 주의
6. 사용자의 공격 프로필 감소
7. 최소한의 권한 원칙 사용
8. 실패 모드에 주의
9. 취약한 가장
10. 관리자가 아닌 사용자가 실제로 사용할 수 있는 응용 프로그램 작성


발췌 : Michael Howard와 Keith Brown의 칼럼 중 / 마이크로소프트
현상 : Oracle Stored Procedure 호출이 제대로 되지 않음
원인 : Stored Procedure에 입출력되는 VARCHAR 변수의 초기화가 되지 않음
조치 : Stored Procedure 입력, 출력 VARCHAR 변수의 Length를 반드시 설정
(TMS에 문제를 일으키는 것으로 보임)
-----
현상 : exec TMS_ORACLE7 -A: Failed.
원인 : ORACLE에서 DB 사용자에게 GRANT(사용허가권)가 없어서 발생하는 문제임.
ORACLE LIB에서 문제가 생길 수도 있다.
조치 : ORACLE의 VIEW중에 V$XATRANS$라는 VIEW를 GRANT시켜주면 조치됨.
ORACLE의 DBA권한에서 실행가능함.
방법: grant all on V$XATRANS$ TO SCRJPCS
여기서 SCRJPCS는 DB USER-ID임.
-----
현상 : DataBase에 연결하지 못한다.
원인 : 1.해당 DataBase에 필요한 환경 설정이 잘못되어 있다.(INVAL Error발생)
2.환경 파일에 환경 설정이 잘못되어 있다.(INVAL Error)
3.DataBase에 권한이 없다.
4.DataBase가 기동되지 않았다.
조치 : 1.set 명령으로 필요한 환경변수 설정을 확인한다.
- Oracle : ORACLE_HOME, ORACLE_SID, ORA_NLS
- Informix : INFORMIXDIR, INFORMIXSERVER
2.구성파일에 설정되어 있는 ENVFILE을 확인한다.
3.해당 User에게 DataBase 권한을 부여한다.
- ORACLE : "v$xatrans$"라는 VIEW에 대하여 해당 User에게 권한을 부여한다.
- INFORMIN : 해당 DB를 사용할 수 있는 권한을 User에게 부여한다.
4.DataBase를 기동하고 Server를 새로 띄운다.
-----
현상 : LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0 PLS-00801: Message 801 not found; product=PLSQL; facility=PCM
22/9 PL/SQL: SQL Statement ignored
28/17 PLS-00201: identifier 'JWONRYO.JWONMAS' must be declared
62/9 PL/SQL: SQL Statement ignored
원인 : 현 Database의 Domain 밖에 있는 Table을 Handling하는 경우에 권한이 없는
경우에 발생
조치 : 접근할 수 있는 권한을 부여한다.
-----
현상 : LINE/COL ERROR
-------- -----------------------------------------------------------------
135/5 PL/SQL: Statement ignored
135/9 PLS-00365: 'AVSQLCODE' is an OUT parameter and cannot be read
원인 : OUT parameter를 IN parameter로 사용하고 그 값을 읽은 경우.
조치 : OUT parameter를 IN OUT parameter로 선언.
-----
현상 : ORA-0020
원인 : 프로세스 수를 프로세스를 초과한 경우.
조치 : 프로세스 수를 들여줌.
-----
현상 : ORA-00023: session references process's private memory; cannot detach session
원인 : XA library를 사용하는데 Oracle이 dedicator server로 설치된 경우 발생
조치 : XA library를 사용할려면 Oracle을 MTS mode로 설치되어야 한다.
-----
현상 : 1.ORA-0054 resource busy and acquire with NOWAIT specified
2.ORA-0054 WHEN DROP A TABLE(SESSION KILL)
원인 : 1.Oracle 사용자가 어떤 Row을 Lock를 했는데, 다른 Oracle 사용자가 NOWAIT문을 이용하여
동일한 Row를 Lock를 한 경우에 발생
2.TABLE에 LOCK이 걸려 DML 및 DDL 명령 사용시
조치 : LOCK을 걸고있는 SESSION들을 KILL
-----
현상 : ORA-0059
원인 : DB_FILES 값에 도달한 경우
조치 : init.ora 의 DB_FILES 를 늘려주고 DB 를 Restartup 하면 해결
-----
현상 : ORA-00210: cannot open control file '/dev/vx/rdsk/oracle/v_ctl1'
ORA-07368: sfofi: open error, unable to open database file.
원인 : Sequent Symmetry or NUMA-Q platform이 very large file (O/S에서 2GB
이상의 file system 지원)을 지원하기 위해 VLFS patch를 적용했거나
VLFS를 이미 지원하는 O/S Version일 경우 오라클 master node가 정상적으로
startup 되고 나서 다른 node가 startup parallel이 될 때 먼저 startup 된
master node가 shared disk 의 모든 오라클 관련 file을
none-shared mode로 open 하기 때문에 위의 현상이 발생됨.
조치 : 1.PTX/Cluster V1.3.2일 경우
* Oracle V7.3.x : O/S상에서 VLFS patch적용하지 않았을 경우는 관계
없으나, 이미 적용되었다면 추가적으로 O/S patch FP#23373
적용하여야 함
2.PTX/Cluster running DYNIX/PTX 4.4.x 일 경우
* Oracle V7.3.3 : 현재 fix된 patch는 없으며 다음과 같은
workaround 방법으로 해결이 가능함.

Workaround)
--- $ORACLE_HOME/rdbms/lib/ins_rdbms.mk file에 아래의 추가된 부분만
삽입하여 오라클 kernel relink 실시
(예:make -f ins_rdbms ioracle)
oracle: $(ORALIBD) $(CORELIBD) $(NETLIBD) $(KSMS) $(CONFIG)
$(PSOLIBLIST) opimai.o @$(ECHO) $(LINK) -o $@ $(LDFLAGS)
$(LDFLAGS_ORA) opimai.o $(CONFIG) \
-llkseqora \ ---> 추가된 부분
$(LLIBSERVER) $(LLIBORA) $(LLIBKNLOPT) $(LLIBSLAX)
$(LLIBPLSQL) \
$(LLIBSICX) $(LLIBSOWSUTL) \
$(LLIBSICX) $(LLIBSOWSUTL) \

...........
...........

* Oracle V7.3.4 :
Oracle V7.3.4 일 경우는 문제가 없으나 patchset을 적용할 경우
V7.3.4.2에서는 V7.3.3과 같은 방법으로 oracle kernel을 relink하면
문제가 해결됨.
-----
현상 : ORA-0376 : file %s cannot be read at this time
원인 : DBF가 파손됨.
조치 : Check the state of the file. Bring it online
-----
현상 : ORA-00376: file 29 cannot be read at this time
ORA-01110: data file 29: '/db/GICORP_4/axix01.dbf'
원인 : datafile의 size가 os에서 허용하는 filesize를 초과해서 발생.
조치 : unix의 ulimit filesize를 확인해 보시기 바랍니다.
그리고 datafile size 보다 크도록 수정해 주어야 합니다.
1.unix ulimit filesize를 증가 시킨다
C shell인 경우
% limit filesize <number>
Bourne 이나 Korn shell 인 경우
$ ulimit -f <number>
2.archivelog mode인지 확인합니다
SVRMGR> select * from v$database;

NAME CREATED LOG_MODE CHECKPOINT ARCHIVE_CH
--------- -------------------- ------------ ---------- ----------
GICORP 05/17/00 13:44:56 ARCHIVELOG 36290290 36284249
1 row selected.
3.media recovery가 필요한 datafiles를 찾습니다
SVRMGR> select * from v$recover_file;

FILE# ONLINE ERROR CHANGE# TIME
---------- ------- ------------------ ---------- --------------------
9 OFFLINE 36287415 12/20/00 23:30:55
23 OFFLINE 36289350 12/21/00 08:40:54
28 OFFLINE 36287415 12/20/00 23:30:55
29 OFFLINE 36287415 12/20/00 23:30:55
37 OFFLINE 36287415 12/20/00 23:30:55
5 rows selected.
4.각각의 datafile에 대해서 다음을 실행해 줍니다
SVRMGR> recover datafile '/db/GICORP_4/axix01.dbf';

Media recovery complete.

SVRMGR> alter database datafile '/db/GICORP_4/axix01.dbf' ONLINE;
Statement processed.

5.database를 restart합니다

SVRMGR> shutdown
Database closed.
Database dismounted.
ORACLE instance shut down.
SVRMGR> startup
ORACLE instance started.
Total System Global Area 54578916 bytes
Fixed Size 69348 bytes
Variable Size 20783104 bytes
Database Buffers 33554432 bytes
Redo Buffers 172032 bytes
Database mounted.
Database opened.
SVRMGR>
-----
현상 : ORA-0312,0313 에러(ONLINE LOG CRASH)
원인 : 1.데이타베이스 STARTUP 시 발생
조치 : [ ONLINE LOG 가 손상되었을때 DB에 OPERATION 이 없었던 경우는 다음과 같은 절차로 DB을
OPEN 할수있다 - 확률 70% ]

1.CONTROLFILE 생성
-. 손상된 online log 는 포함시키지 않는다.
-.resetlogs option 으로 생성한다.
-.reuse option 은 생략하고 기존 controlfile 은 다른이름으로 move 시킴.

<V7 에서 CONTROLFILE 생성하는 방법 >
sqldba> startup mount
sqldba> alter database backup controlfile to trace;

위와 같이 명령을 입력하면 ORACLE_HOME/rdbms/log 디렉토리에 트레이스 화일이
생긴다. 그 트레이스 화일에서 create controlfile 명령부분을 남기고 삭제한다.
콘트롤화일 생성 문장 예 - <cnt.sql> : GROUP 1 이 ONLINE LOG 라고 가정
---------------------------------------------------------------------
CREATE CONTROLFILE DATABASE "RC722" RESETLOGS NOARCHIVELOG
MAXLOGFILES 32 ********
MAXLOGMEMBERS 2
MAXDATAFILES 30
MAXINSTANCES 8
MAXLOGHISTORY 800
LOGFILE
GROUP 2 '/oracle/oracle/dbs/log2RC722.dbf' SIZE 5M,
GROUP 3 '/oracle/oracle/dbs/log3RC722.dbf' SIZE 5M
DATAFILE
'/oracle/oracle/dbs/systRC722.dbf',
'/oracle/oracle/dbs/rbsRC722.dbf',
'/oracle/oracle/dbs/toolRC722.dbf',
'/oracle/oracle/dbs/usrRC722.dbf',
'/oracle/oracle/dbs/tempRC722.dbf',
'/oracle/oracle/rcdata.dbf'
;
2.절차
$ sqldba lmode=y
SQLDBA> connect internal
SQLDBA> shutdown abort
SQLDBA> startup nomount
statement processed
SQLDBA> @cnt
SQLDBA> recover database using backup controlfile until cancel;
....
...
CANCEL (Return)
Recovery canceled
SQLDBA> alter database open resetlogs;

: 만일 정상적으로 open 되면 log file 추가
SQLDBA> alter database add logfile '?/dbs/log1ORA722.dbf' size 1M;
: 정상적으로 open 안되면 RC에 다시 연락
-----
현상 : ORA-0439
원인 : BITMAP INDEXES 생성 시 option 이 인스톨되지 않아서 발생
조치 : 반드시 Oracle 8 Enterprise Edition 에서만 사용이 가능하다.
Oracle 8i 에서도 동일하게 적용된다.
-----
현상 : ORA-0600[3339] DATA BLOCK CORRUPTION DETECTION
[3339] [arg1] [arg2] [] [] [] []
ORA-1578 : Data block corrupted in file # block #
원인 : 1.ORACLE이 직접 버퍼로 데이타를 읽어들일 때 읽은 블럭의 DBA(Data Block Address)가 잘못
되었음(INVALID)을 의미
2.ORACLE의 문제가 아니라 OS나 HW의 문제인 경우가 많다.
-----
현상 : ORA-0604: error occurred at recursive SQL level %s
원인 : 1.내부적으로 SQL명령이 실행될 때 발생(현재 할당된 익스텐트가 가득 차서 다음 익스텐트를
할당 받으려고 할 때 오라클이 다음 익스텐트의 크기와 위치를 결정하기 위하여 SELECT
명령을 내리게 되는 것과 같은 경우)
2.init.ora 화일의 파라미터 가운데 DC_FREE_EXTENTS 나 ROW_CACHE_ENQUEUES 의 값이 너무
작게 설정
3.테이블 스페이스가 가득 차거나 Extent 갯수의 최대 허용값을 초과해서 에러가 발생하는
경우 ORA-604 에러가 함께 발생
조치 : 1.?/dbs/init<SID>.ora 화일에 지정된 open_cursors 의 크기를 알아보는 것이다. 이 값이
설정이 안되어 있으면 Default가 50이므로
open_cursors=255
----------------
2.DC_FREE_EXTENTS 나 ROW_CACHE_ENQUEUES들의 값을 크게 설정
3.에러의 원인을 찾기 위해서 init.ora 화일에 다음과 같은 라인을 추가한다.
events = "604 trace name errorstack"
이렇게 init.ora를 변경하고 DB를 Shutdown 하고 Startup 하면 ORA-0604 에러가 발생하는
경우에 자세한 정보를 Trace 화일에 기록해 주므로 이 화일을 검사하여 에러의 원인을
찾을 수 있다.
-----
현상 : ORA-0901 invalid CREATE command
원인 : CREATE 뒤에 오는 KeyWord를 식별하지 못한 경우
-----
현상 : ORA-0902 invalid dadatype
원인 : Oracle에서 제공되지 않은 datatype를 사용한 경우
-----
현상 : ORA-0903 invalid table name
원인 : 테이블의 이름이 Oracle object 명명에 대한 필요조건을 만족시키지 못한 경우
-----
현상 : ORA-0904 열명이 부적합합니다.
원인 : 컬럼이 테이블에 존재하지 컬럼을 사용한 경우
-----
현상 : 083147.gold!stmkdjc.22031: LIBTUX_CAT:522: INFO: Default tpsvrdone() function
used
ORA-0904 : invalid column name
ORA-1003 : no statement parsed
원인 : 1.해당 Table에 존재하지 않은 Field를 사용한 경우
2.Host Variable 앞에 ":"를 덧붙지지 않은 경우
3.해당 Table를 변경하고 관련된 프로그램을 컴파일하지 않은 경우
조치 : 1.해당 Table에 Column이 존재하는지 확인
2.Host Variable 앞에 ":"를 덧붙인다.
3.해당 Table에 관련된 프로그램를 컴파일한다.
-----
현상 : ORA-0906 missing left parenthesis
원인 : 왼쪽 괄호를 찾지 못한 경우에 발생
-----
현상 : ORA-0907 missing right parenthesis
원인 : 오른쪽 괄호를 찾지 못한 경우에 발생
-----
현상 : ORA-0910 specified legth too long for its datatype
원인 : 특정 datatype의 길이가 허용 최대 길이를 초과한 경우
-----
현상 : ORA-0911 invalid character
원인 : Oracle이 뮤효 문자라고 간주하는 것을 만날 때 발생한 에러로 실제문제는 없어진 문자때문
-----
현상 : ORA-0913 too many value
원인 : INSERT문에서 지정된 열의 수보다 열 값의 수가 적으면 발생
-----
현상 : ORA-0917 missing comma
원인 : 1.Comma를 기대하고 있는 SQL문에 comma가 없는 경우
2.오른쪽 괄호가 없는 경우에도 발생
-----
현상 : ORA-0918 column ambiguously defined
원인 : 1.둘 이상의 테이블이 한 SQL문에서 참조될 때 발생
2.한개 이상의 지정된 테이블에 존재하는 어떤 열이 해당 테이블로 한정받지 못한 경우
-----
현상 : ORA-0920 invalid relational operator
원인 : 관계 연산자를 식별하지 못한 경우
-----
현상 : ORA-0921 unexpected end of SQL command
원인 : 불완전한 SQL문일 경우에 발생
-----
현상 : ORA-0922 missing or invalid option
원인 : option에 임의의 문자가 삽입됨(예:NOT NULL --> NOT_NULL)
-----
현상 : ORA-0932 inconsistent datatype
원인 : 1.어떤 연산자를 어떤 열에 적용시키려고 하는데 그것의 datatype을 연산자와 함께 사용한 경우
2.ORA-0997 illegal use of LONG datatype을 복귀시킬 가능성
-----
현상 : ORA-00933: SQL command not properly ended
원인:
-----
현상 : ORA-0934 group function is not allowed here
원인 : SQL문의 WHERE구나 GROUP BY구에서 Group function를 사용한 경우
-----
현상 : ORA-0936 missing expression
원인 : 1.Comma 기술 뒤에 열이나 표현식이 존재하지 않은 경우에 발생
2.ORA-0917 missing comma을 복귀시킬 가능성
-----
현상 : ORA-0937 not a single-group group function
원인 : 어떤 SQL문의 선택 list는 어떤 열이 GROUP BY구에서 참조되지 않으면 그열과 Group function를
포함할 수 없다.
-----
현상 : ORA-0938 not enough arguments for function
원인 : SQL문이 불충분한 수의 인수로 함수를 호출한 경우에 발생
-----
현상 : ORA-0942 : table or view does not exist(테이블 또는 뷰가 존재하지 않습니다.)
원인 : Oracle은 테이블이나 뷰가 존재하지만 사용자가 테이블이나 뷰를 위한 오브젝트 특권(Grant)을 부여하지 않음
조치 : Table 생성 및 권한부여
-----
현상 : ORA-0947 not enough values
원인 : INSERT문에서 지정된 열의 수가 열 값의 수보다 클때 발생
-----
현상 : ORA-0979 not GROUP BY expression
원인 : 어떤 query의 선택 list 안의 한 열이 GROUP BY구에 들어있고 다른 열은 들어있지 않은 경우에 발생
-----
현상 : ORA-0997 illegal use of LONG datatype
원인 : 1.어떤 기능들은 datatype이 LONG인 열에서 수행되지 않는다.
2.Long column은 2G까지 지원을 하지만,
SQL*Plus에서 insert into 문장을 이용하여 long column에 넣을 문자열을
single quote(') 안에 기술 시, 2000 characters가 넘으면 ora-1704 에러가 난다.
조치 : 1.TABLE의 COPY는 가능하지 않으므로,LONG COLUMN을 가진 테이블을 COPY하고자 할 때,
32KBytes 이하의 size라면 다음의 PL/SQL을 사용하면 가능하다.
2.PL/SQL을 이용해야 하며, 경우에 따라 Pro*C, SQL*Loader 등을 이용하여 insert해야만 한다.
-----
현상 : ORA-1001 Invalid Cursor
원인 : Typing 에러, 잘못된 메모리 관리 등의 여러가지 원인에 의해서 발생.
조치 : 1.환경에서 조치할 사항
- PRECOMPILE 옵션 가운데 MAXOPENCURSORS 를 늘려준다.
- init<SID>.ora 화일에서 OPEN_CURSORS 파라미터 값을 늘려준다.
- 사용되지 않는 CURSOR는 OPEN 상태로 두지 말고 CLOSE 시켜준다.
- 지금은 거의 사용되지 않지만 ORACLE V6 를 사용한다면 PRECOMPILE 옵션 가운데
AREASIZE를 512K 정도로 크게 늘려주도록 한다. 그리고 init<SID>.ora 에서
CONTEXT_AREA 값도 늘려준다 .
- TRACE FILE을 이용하면 문제의 원인을 찾는데 있어 유용할 때가 있다.
2.그 밖의 경우
- OPEN 되지 않은 CURSOR 에 대해서 작업을 할 때
- 존재하지 않는 OBJECT에 대해서 SQL 명령을 실행할 때
- CURSOR CACHE로부터 삭제된 경우
- CURSOR CACHE로부터 삭제된 또다른 경우
PRECOMPILE 옵션 가운데에서 MAXOPENCUSORS 를 늘려주거나
HOLD_CURSOR=YES, RELEASE_CURSOR=NO 로 설정
- XA/TUXEDO 환경에서 ORA-1001 에러가 발생하는 경우(일부 ORACLE 버젼에서 발생)
-----
현상 : ORA-1002 FETCH OUT OF SEQUENCE IN PRO*C(stop[<fltmsjaud>]:리스너를 중단합니다.
원인 : 1.user가 더이상 유효하지 않은 cursor로부터 fetch를 하려고 하기 때문
2.ORA-1403 등과 같이 NO DATA FOUND를 return하는 fetch작업을 수행할때
3.SELECT FOR UPDATE를 가진 cursor 의 fetch작업내에 commit이 있는 경우
조치 : 3.commit을 fetch loop의 바깥쪽으로 빼거나 select for update문을 사용하지 않아야 한다.
-----
현상 : ORA-1012 Error( not logged on )가 발생
원인 : 1.tpbegin()이 되어 있지 않음
2.PC쪽에서 NOTRAN Mode로 Service를 호출
조치 : 1.Program을 확인한다.
2.flag를 0으로 Setting한다.(TRAN Mode로 Service 호출)
3.Service절에 Default에 AUTOTRAN을 "Y"로 설정하고 해당 Service명을 기술한다.
-----
현상 : ORA-1027 bind variables not allowed for data definition operations
원인 : WHERE에 BIND_VAR 를 이용한 CREATE VIEW 는 불가능
조치 : 이 경우 EXEC SQL CREATE TABLE IMAGE
(EMPNO NUMBER(4) NOT NULL, BITMAP LONG RAW)
END-EXEC.
이 처럼 create 해야 한다.
-----
현상 : ORA-1031 insufficient privileges
원인 : 사용자가 테이블이나 뷰와 연관된 적어도 한 개의 object 특권을 부여받았지만 SQL문에서 지정된
특권을 부여받지 않았을 때 발생
1.ORACLE의 SYSTEM 유저에 POWERBUILDER의 BASE TABLE 5개가 생성이 되어 있지
않은 경우
2.SYSTEM 유저로 접속한 후에도 일반 유저가 접속이 되지 않을 경우
조치 : 1.5개 base table(pbcatcol, pbcattbl, pbcatfmt, pbcatvld, pbcatedt)을
drop한 다음 system 유저로 접속을 하고, 다시 일반 유저로 접속하는 방법.
2.system 유저로 들어가서 5개 base table에 대한 사용 권한을
일반 유저에게 주는 방법.
$sqlplus system/manager

SQL>grant all on pbcatcol to public;
SQL>grant all on pbcatedt to public;
SQL>grant all on pbcatfmt to public;
SQL>grant all on pbcattbl to public;
SQL>grant all on pbcatvld to public;
-----
현상 : ORA-1034, "ORACLE not available"
ORA-7320, "smsget: shmat error when trying to attach sga."
ORA-7429, "smsgsg: shmget() failed to get segment."
원인 : ORACLE DBA 사용자만 데이타베이스를 ACESS할수 있고 다른 사용자는 SQL*PLUS 등을 통하여
CONNECT를 하려고 할때 다음 에러가 발생 할경우
-----
현상 : TPFAILED ......................
sqlca.sqlcode ==> -1036
ORACLE에서 단독으로 실행하면 문제가 발생되지 않고 OUTPUT을 정확하게 출력하지만
TP/M와 함께 실행이 되면 SQL SELECT문을 수행하지 못하고 sqlca.sqlcode ==> -1036의
MESSAGE를 뿌리고 실행을 멈춘다.
원인 : ORACLE에서 Version간의 Segment 정의부분이 다르기 때문
조치 : makefile 혹은 proc.mk file에서
sqlcheck=semantic userid=scrjpcs/scrjpcs를 포함시킨다.
-----
현상 : ORA-1039: insufficient privileges on underlying objects of the view.
원인 : SYS user가 아닌 다른 user로 SQL Analyze에 로그인하여 SQL statement에 대한 explain plan 옵션을 사용할 때 다음과 같은 에러가 발생
조치 : 1.dictionary table/view들을 validate시켜 놓으려면 dba가 read 권한만 SQL Analyze를 수행하는 user에게 grant하면 충분하다.
2.SYS user로서 SQL explaining을 수행하는 것이다.
-----
현상 : ORA-9992 scumnt: failed to open <FILENAME>
ORA-9993 scumnt: failed to lock <FILENAME>
ORA-1102 cannot mount database in exclusive mode
원인 : 서로 독립적인 두개의 instance가 동일한 database file들을 동기화 (synchronisation)없이 access할 수 있기 때문에 database corruption을 유발시킬 수 있었다.
조치 : database의 db_name이 변경되면 각각의 lk<DB_NAME> file을 생성.
-----
현상 : ORA-01118: cannot add any more database files: limit of XXX exceeded
원인 : 데이타 화일의 갯수가 MAXDATAFILES 값에 도달한 경우 발생
조치 : MAXDATAFILES를 늘리기 위해서는 DB를 새로 만들어야 하며 그 이후 버젼을 사용중이라면 콘트롤
화일을 새로 만들어서 MAXDATAFILES를 늘릴 수 있다
-----
현상 : ORA-1157 : cannot identify data file 11 - file not found
ORA-1110 : data file 11 : '/user1/oracle7/dbs/user2.dbf'
원인 : OS 명령으로 DATA FILE 을 삭제한 경우
조치 : DATABASE STARTUP시 STARTUP MOUNT 단계까지 실행한 후, 문제의 데이타 화일을 OFFLINE 시킨다.
데이타베이스를 오픈한다. 단 데이타베이스 오픈이 정상적으로 수행되면 문제가 발생한 데이타
화일을 포함하고 있는 TABLESPACE를 DROP하지 않을 경우에는 DATABASE STARTUP시 항상 데이타
화일의 오픈 단계에서 에러가 발생된다. 따라서, 문제의 데이타 화일의 OFFLINE과 TABLESPACE의
DROP전에 반드시 해당 TABLESPACE를 사용하고 있는 USER의 데이타 백업을 수행해야 한다.

데이타 화일의 OFFLINE과 관련된 명령은 다음과 같다.
SQLDBA를 COMMAND LINE MODE로 기동시킨다.

$ sqldba lmode=y
SQLDBA> CONNECT INTERNAL;
SQLDBA> STARTUP MOUNT;
ORACLE instance started.
Database mounted.
SQLDBA> ALTER DATABASE DATAFILE '/user1/oracle7/dbs/user2.dbf'
OFFLINE DROP;
Statement processed.
SQLDBA> ALTER DATABASE OPEN;
Statement processed.
SQLDBA> DROP TABLESPACE tablespace_name INCLUDING CONTENTS;
Statement
-----
현상 : ORA-01237 cannot extend datafile %s
원인 : O/S 레벨에서는 file size를 1TB 이상 지원한다고 하는데, oracle datafile을 2G 이상으로 resize하려고 한다거나 tablespace에 datafile을 추가하거나 생성할 때, 2G 이상 주면 file size limit에 걸리는 현상 발생
조치 : 화일 시스템에서 large file을 사용하기 위해서는 화일 시스템을 'largefiles' option으로 mount해야 한다.
-----
현상 : ORA-1400 primary key or mandatory(NOT NULL) column is missing or NULL during insert
원인 : 어떤 필수적인 열을 위한 값을 공급하지 않은 경우
-----
현상 : ORA-1401 inserted value too large for column(열에 입력한 값이 너무 큽니다.)
원인 : 문자열을 할당하고자 할때 길이가 최대치를 초과한 경우
-----
현상 : ORA-1403 no dada found
원인 : 사실상 전혀 Error가 아니다.
-----
현상 : ORA-1405 fetched column value is NULL
원인 : ERROR 가 아니고 WARNING MESSAGE 이다.
조치 : dbms=v6 를 PRECOMPILER OPTION 에 추가해준다. dbms=v6 로 SETTING 할경우는 HOST 변수에
NULL 이 RETURN 되더라도 sqlca.sqlcode 는 0 이 된다.
-----
현상 : ORA-1407 cannot update mandatory(NOT NULL) column to NULL
원인 : 필수적인 열의 값을 NULL에 설정한 경우에 발생
-----
현상 : ORA-1408 such column list already indexed
원인 : 이미 동일한 열 List에 기초한 Index를 갖고 있는 Table에서 Index를 작성하고자 하는 경우에 발생
-----
현상 : ORA-1410 invalid ROWID
원인 : 1.적절한 Format으로 ROWID를 상술하지 않은 경우에 발생
2.지정된 ROWID가 존재하지 않은 경우에 발생
-----
현상 : ORA-01438: 지정한 정도를 초과한 값이 열에 지정되었습니다.
원인 : 지정한 자릿수를 초과한 Column이 존재한 경우에 발생
-----
현상 : ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYS.STANDARD", line 648
ORA-06512: at "BETH.BETH", line 6
ORA-06512: at line 1
원인 : SELECT 문에서 조건에 해당하는 row가 2건 이상
return되었을 때 발생하는 TOO_MANY_ROWS 에러와 동일한 에러이다.
조치 : 확인한 결과 DUAL table에서는 비록 2개의 ROWID를 볼 수는 없지만,
실제 2개의 row가 DUAL table에 존재하는 상황이다.
따라서, 다음 명령을 이용하여 여분의 필요없는 row를 delete해야 한다.
-----
현상 : ORA-1449 column contains NULL values; cannot alter to NOT NULL
원인 : 어떤 열을 필수적인 것으로 변경하고자 하나 적어도 테이블 내의 한 행이 그 열을 위한 NULL값을
가질 때 발생
-----
현상 : ORA-1452 cannot CREATE UNIQUE INDEX; duplicate keys found
원인 : 값이 독특하지 않은 일련의 열에서 독특한 인덱스를 작성한 경우에 발생
-----
현상 : ORA-1453 SET TRANSACTION must be first statement of transaction
원인 : 모종의 다른 SQL문 이후에 SET TRANSACTION문을 기동할 때 발생
-----
현상 : ORA-01458 Invalid length inside variable character string
원인 : DB Table field의 길이와 Host Variable의 길이 차이가 있을때 발생한다.
그러므로 Table field의 길이와 Host Variable의 길이를 비교해 본다. 혹은 Stored
Procedure의 Input Parameter가 Null 값으로 넘겨질 때도 발생한다.
조치 : DB Table field와 Host Variable의 길이를 조정한다.
Stored Procedure의 Input Parameter에 Null값을 0의 값을 채워서 넘긴다.
주의 : Stored Procedure에서 Cursor를 사용할 때
FOR ... LOOP를 사용할 때 주의를 해야한다.
FOR i IN 1..batch_size LOOP
FETCH get_emp
INTO
emp_name( i )
,job( i )
,sql( i )
;

IF get_emp%NOTFOUND THEN -- if no row was found
CLOSE get_emp;
done_fetch := 100; -- indicate all none
EXIT;
ELSE
done_fetch := 900; -- indicate all none
found := found + 1; -- count row
END IF;
END LOOP;
에서 Fetch Array의 0번째에 Data를 저장할 때 문제가 생긴다.
그러므로, emp_name( 0 )이라고 하면 Error를 발생한다.
-----
현상 : ORA-01476: divisor is equal to zero
원인 : Zero값으로 임의의 수를 나누었을때 발생
-----
현상 : ORA-01480: trailing null missing from STR bind value
원인 : 1.해당 Column의 Size 보다 더 큰 값이 들어온 경우에 발생
2.Character Type(CHAR, VARCHAR)의 Host variable인 경우 변수 선언시 Table의 Column size 만큼의 변수길이를 선언한 경우 발생
조치 : 1.해당 Column의 Size와 해당값을 확인
2.Character Type(CHAR, VARCHAR)의 Host variable인 경우 변수 선언시 Table의 Column size에 1를 더해 주어야 한다.
(데이터의 마지막에 NULL 문자를 포함해야 하기 때문에)
-----
현상 : ORA-1481 invalid number format model
원인 : 어떤 숫자 Format Model이 미정의 문자를 포함한 경우에 발생
-----
현상 : ORA-1547 : Failed to allocate extent of size 'num' in tablespace 'TOOLS
원인 : TABLESPACE가 에러에 명시된 ORACLE block 수 만큼의 요청된 EXTENT를 할당할 충분한 FREE
SPACE를 갖고있지 못할 경우에 발생
조치 : 1.해당 TABLESPACE내에서 연속된 영역의 ORACLE block 할당할 수 있도록 데이타 화일을 추가
2.TABLE의 STORAGE PARAMETER에서 INITIAL EXTENT, NEXT EXTENT의 크기를 조정하여 TABLE을
재구축
3.다음의 방법으로는 관련 TABLESPACE를 재구성하는 것
-----
현상 : ORA-1552 (CANNOT USE SYSTEM ROLLBACK SEGMENT FOR NON-SYSTEM TABLESPACE '%S')
원인 : SYSTEM TABLESPACE 이외의 TABLESPACE를 포함한 OPERATION을 위하여 SYSTEM TABLESPACE의
ROLLBACK SEGMENT를 사용할 경우에 발생
조치 : SYSTEM TABLESPACE에 하나 이상의 ROLLBACK SEGMENT를 추가한 다음, 데이타베이스 오브젝트를
생성
-----
현상 : ORA-1555 Snapshot Too Old
원인 : 1.데이타의 변경이 심한 데이타베이스에서 롤백 세그먼트의 갯수와 크기가 작을 경우에 발생
2.롤백 세그먼트가 손상되어 읽을 수 없게 된 경우
3.Fetch Across Commit(테이블에 대하여 Query가 커서를 열고 루프 내에서 데이타를 Fetch
하고 변경하고 커밋하는 과정에서 발생)
4.Delayed Block Clean Out(데이타 블럭이 변경되고 커밋되면 오라클은 롤백세그먼트 헤더에
그 트랜잭션이 커밋되었다고 기록하지만 데이타 블럭을 바로 변경하지는 않는다 (Fast
Commit). 그리고 다음 트랜잭션이 변경된 블럭을 요구할 때야 비로소 변경 시키는것
조치 : 1.커서가 Open된 상태에서는 커밋을 자주하지 않고 롤백 세그먼트 크기를 키워 나가도록
2.커서를 사용하기 전에 Full Table Scan을 해주면 예방이 가능
-----
현상 : ORA-1562(Failed to extend rollback segment(id = %s))
원인 : 1.사용중인 ACTIVE 상태의 ROLLBACK SEGMENT가 다음 EXTENT를 할당하고자 할 경우
2.해당 ROLLBACK SEGMENT에 대하여 발생 가능한 최대 EXTENT 수를 초과할때 발생
조치 : ROLLBACK SEGMENT의 재생성
-----
현상 : ORA-01578: ORACLE data block corrupted (file # 6, block # 3)
ORA-01110: data file 6: '/tmp/ts_corrupt.dbf'
원인 :
조치 : 해당 objects를 drop하고 recreate하여 처리
-----
현상 : ORA-01578
원인 : data block 에 corruption 이 생긴 경우에 발생.
조치 : 1.최선의 해결책은 backup 받아둔 file 을 restore 한 후 recover 작업을 하는 것이다.
2.backup datafile 을 restore 하고 recover 하지 않을 것이라면 우선, 어떤 object 에서 corruption 이 발생하였는지 확인해야 한다.
3.해당 segment 가 non-data dictionary index 라면, 해당 index 를 drop 한 후 재생성한다.
4.해당 segment 가 table 이라면, corruption 이 발생한 block 의 data 는 소실된 것이다.
5.만약 해당 table 에 대한 최근의 export dump file 이 존재한다면, 해당 table 을 drop 한 후 import 함으로써 복구할 수 있다.
6.corruption 이 발생한 non-clustered table 에서 corrupted block 을
access 하지 않고 나머지 data 들을 select 할 수 있도록 ROWID 를 이용할
수 있다.
7.만약 data dictionary 에 속하는 table, index 또는 rollback segment에
corrupted block 이 발생하였다면 Oracle Support 의 지원을 받는다.
8.일반적으로, ORA-1578 은 hardware 의 문제때문에 유발된다. 하지만 만약에
ORA-600[3374] 가 발생한다면 memory 상에서 corruption 이 발생한
경우이다. 이 경우 database 를 restartup 하면 문제가 해결될 수 있다.
-----
현상 : ORA-1591(Pending Transaction의 처리)
원인 : 분산 트랜잭션의 경우 2 phase commit수행 단계중에 fail이 발생하게 되면 관여된 일부 database에서는 rollback 혹은 commit이 되고, 일부는 distributed lock이 걸린 상태로 계속 지속될 수 있다.
이렇게 pending된 transaction에 대해서는 기본적으로 Oracle의 background process인 RECO process가 자동으로 정리하여 주나, 경우에 따라 자동으로 정리가 되지 못하는 상황이 발생
조치 : STEP 1: alert.log file을 check한다.
STEP 2: network 환경을 확인한다.
STEP 3: RECO process가 떠 있는지 확인한다.
STEP 4: DBA_2PC_PENDING을 조회해 본다.
STEP 5: DBA_2PC_NEIGHBORS view를 조회해 본다.
STEP 6: commit point site를 확인한다.
STEP 7: DBA_2PC_PENDING의 MIXED column을 확인한다.
STEP 8: DBA_2PC_PENDING의 STATE column의 값을 확인한다.
STEP 9: 불일치 사항을 파악하고 DBA_2PC_PENDING을 정리한다.

2PC에서 1st phase commit(xa_prepare)이 정상적으로 종료되면 Oracle의 dba_pending_transaction에 해당
Transaction에 대한 정보가 나타난다.

formatid 40
globalid 636861656A750000000000000000000000000000000000
5B5103A6BEC9900000DE8
branchid 0000006600000065

이 상태에서 일정한 시간 내에 2nd phase commit(xa_commit)에 끝나지 않으면 dba_2pc_pending에도 이
Transaction이 나타난다.

local_tran_id 4.24.3026
global_tran_id 40.636861656A750000000000000000000000000000000000
5B5103A6BEC9900000DE8
state prepared
mixed no
advice
tran_comment
fail_time
force_time
retry_time
os_user jun
os_termina
host chaeju
db_user
commit# 5332231

위에서 "일정한 시간"이란 용어를 사용했는데 Oracle의 문서에는 이에 관한 정확한 언급은 없다.
다만, 다른 Transaction에서 해당 레코드를 참조하려고 할 때 이미 lock이 걸려 있으므로 대기하는
시간에 대해서는 init.ora에서 지정하는 distributed_lock_timeout에 대해서만 언급하고 있다. 그런데
oracle 8.1.7에서는 distributed_lock_timeout을 설정하면 obsolete로 나온다.

이 시간 동안에 해당 레코드에 대한 lock이 풀리지 않으면 아래와 같은 에러를 만난다.

ORA-02049: time-out: distributed transaction waiting for lock

위의 에러가 발생한 이후에 이 레코드를 참조하려고 하면 1591 에러가 나타난다.

ORA-01591: lock held by in-doubt distributed transaction '4.24.3026'

보는 것처럼 ORA-01591 에러 메시지에는 local_tran_id가 있다. 이를 이용하여 dba_2pc_pending에서
global_tran_id를 조회하고, 이 데이터는 dba_pending_transaction의 formatid와 globalid로 이루어져
있으므로 이를 이용하여 dba_pending_transaction에서 branchid도 얻을 수 있다.

이들로 부타 아래와 같이 XID를 얻을 수 있다.

xid.formatid = dba_pending_transactions.formatid
xid.gtrid_length = len(dba_pending_transactions.globalid)
xid.bqual_length = len(dba_pending_transactions.branchid)
xid.data = dba_pending_transactions.globalid + dba_pending_transactions.branchid

여기까지는 Oracle로 부터 XID를 얻는 과정이다.

tpconvert(str, (char *)&xid, TPTOSTRING | TPCONVXID)를 이용하여 XID의 string 표현을 얻을 수 있고
이값을 이용하여 .TMIB 서비스를 호출하면 아래와 같은 정보를 얻을 수 있다.

TA_ERROR 0
TA_MORE 0
TA_OCCURS 1
TA_GRPCOUNT 2
TA_GRPINDEX 0
TA_GRPNO 102
TA_GRPNO 101
TA_TIMEOUT 9
TA_COORDGRPNO 102
TA_CLASS T_TRANSACTION
TA_STATE READY
TA_COORDLMID SITE1
TA_GSTATE READY
TA_GSTATE READY
TA_TPTRANID 0x0 0x3a6bec99 0xde8 0x28 0x0 0x0
TA_XID 0x0 0x3a6bec99 0xde8 0x28 0x66
TA_COORDSRVGRP APPGRP2
TA_LMID SITE1
TA_SRVGRP APPGRP2
TA_SRVGRP APPGRP1

위의 경우에는 아직 Tuxedo가 transaction에 대한 정보를 가지고 있기 때문에 별다른 조치가 필요없다.
하지만, Oracle의 dba_2pc_pending에는 있는데 Tuxedo에서 해당 Transaction에 대한 정보를 가지고
있지 않은 경우에는 Oracle에서 rollback force나 commit force를 이용하여 pending transaction을
정리해 주어야만 lock이 풀린다.
-----
현상 : ORA-1628, 00000, "max # extents (%s) reached for rollback segment %s"
ORA-1630, 00000, "max # extents (%s) reached in temp segment in tablespace %s"
ORA-1631, 00000, "max # extents (%s) reached in table %s.%s"
ORA-1632, 00000, "max # extents (%s) reached in index %s.%s"
원인 : 오브젝트의 익스텐트가 MAX # 에 도달 했기 때문에 발생되며 오브젝트의 MAXEXTENTS는
STORAGE 의 MAXEXTENTS 파라미터에 의해 결정
조치 : ALTER TABLE .. STORAGE (MAXEXTENTS n)를 사용하여 최대 MAXEXTENTS 값보다 작은 수로
MAXEXTENTS를 늘려준다.
-----
현상 : ORA-1652, 00000, "unable to extend temp segment by 6144 in tablespace "VESSEL"
원인 : 테이블이나 인덱스 등을 만들 때 자신의 TEMP TABLESPACE 가 아닌 곳에서 ORA-1652(temp
tablespace가 부족함) 에러가 발생
조치 : 에러메시지에서 보여주는 대로 해당 테이블스페이스에 Temporary Segment 가 생성될 만한
연속된 공간을 마련하여 주는 것
-----
현상 : ORA-1653
원인 : 특정 tablespace 에 space 가 부족해서 table의 extent가 일어나지 못해서 발생
조치 : user의 default tablespace 를 변환한 후, 이 default tablespace
안에 create table을 다시 한 후 sql*loader 를 실행한다
-----
현상 : ORA-1654 ERROR ON INDEX SEGMENT
원인 : tablespace가 적어 extent 영역을 할당할 수 없어서 발생
조치 : datafile을 추가 시 이전값 이상의 사이즈를 추가해야 함.
-----
현상 : ORA-1722 invalid number
원인 : 수치값이 불법일 경우
-----
현상 : ORA-1747 열명을 올바르게 지정해 주십시요.
원인 : 열명이 다른 경우(SQL문장 기술시 첫번째 열명 앞에 Comma를 삽입한 경우)
-----
현상 : tb_ra315 insert error ORA-02291: integrity constraint (SCRJAPPR.A315_E007_FK)
violated - parent ....
원인 : Table과 관련된 Reference 관계로 parent table의 data가 없는 관계로 data 입력불가
조치 : Reference 관계를 끈어주든지 아니면 관계된 Table에 Data를 모두 입력하는 방법.
-----
현상 : ORA-02303: cannot drop or replace a type with type or table dependents
원인 : Type이나 table의 dependency가 있는 type을 drop하거나 replace하고자 할 때 발생.
조치 : SQL Reference guide에 의하면 DROP TYPE FORCE 옵션은 recommend하지 않는다.
왜냐하면 이 옵션을 쓰게 되면 복구가 불가능하고 dependency가 있던 table들은
access하지 못하는 결과를 초래한다.
-----
현상 : ORA-03113: end-of-file on communication channel
원인 : 1.이전에 작동했던 해당 instance의 shared memory segment들이 아직 system에 남아있어서 발생.
2.서버의 Oracle 쉐도 프로세스가 예기치 않게 종료된 경우 발생.
3.SQL*NET 드라이버가 Unix의 ORACLE 실행 파일과 연결되지 않아 발생한 경우.
4.서버쪽의 기계 손상이나 네트워크 고장인 경우.
5.네트워크에서 두 서버가 같은 노드 이름을 가질 때에도 이 오류가 발생.
6.모든 원인은 결국 클라이언트가 서버로부터 어떤 정보를 읽으러 갔다가 거기서 더 이상 연결이 없음을 발견했다는 뜻임.
7.Oracle XA를 사용하는 AP 서버 혹은 TMS 서버가 떠 있는 상황에서 연결된 DB를 재기동 시키거나 혹은 다른 문제로 인해서 데이터베이스와의 연결이 끊어진 경우에 발생
조치 : shared memory를 check하여 oracle이 소유하고 있는 shared memory segment를 삭제하여 문제를 해결.
자동으로 재접속을 하기 위해서는 TUXWA4ORACLE(WorkAround For Oracle) 환경변수를 1로 설정하면 해당 서버가 오라클에 접근하여 3113 에러가 발생하는 순간에 재접속이 이루어진다.
(XA 서버에만 해당되며 Non-XA 서버의 경우는 사용자 coding에 의해서 동일한 기능을 구현할 수 있다.)
-----
현상 : ORA-3114 Error( not connected to ORACLE )가 발생
원인 : ORACLE이 Shutdown 되었다.
조치 : ORACLE이 떠 있는지 확인하고, Server를 새로 기동한다.
-----
현상 : ORA-3121
원인 : SQL*NET V2를 통해 연결하려 할 때 연결 스트링에 'tns:'net접두어를 사용하지 않은 경우
조치 : 구버전인 SQL*NET V1의 net 접두어 (SQL*Net TCP/IP에 대한 "t:"등)를 사용하지 않도록 주의
하십시요.
-----
현상 : ORA-4068 existing state of packages%s%s%s has been discarded
원인 : 응용프로그램 실행 중에 사용하고 있는 Stored Procedure를 Compile하는 경우에 발생
조치 : 응용프로그램을 재기동시킨다.
-----
현상 : ORA-4091 table name is mutating, trigger/function may not see it
원인 : DataBase Trigger가 Transaction 내에서 변경된 테이블에 대하여 Query를 기동할 때 발생
조치 : 1.PL/SQL table을 생성한다.
2.BEFORE STATEMENT trigger를 생성한다.
3.AFTER ROW trigger를 생성한다.
4.AFTER STATEMENT trigger를 생성한다.
5.data insert 및 확인
-----
현상 : ORA-4092 cannot COMMIT or ROLLBACK in a trigger
원인 : 1.Trigger가 COMMIT or ROLLBACK을 실행하고자 할 때 발생
2.Trigger가 내장 프로시저, COMMIT나 ROLLBACK될 함수, 패캐지 서브프로그램을 호출한 경우
-----
현상 : ORA-6106,ORA-6120 NETTCP : socket creation failure
원인 : WIN V1.X용 SQL*NET TCP/IP는 SQLTCP.DLL과 SQLTCP1.DLL들은 ORACLE용 연결 스트링이 TCP/IP
프로토콜 스트링으로 변환되면 OCI DLL에 의해 작업 진행중에 올려집니다. ORACLE INTERFACE
DLL은 SQLTCP.DLL을 먼저 올리려고 합니다. 이것이 실패하면 DOS TSR 버전의 드라이버를
찾습니다. 두 가지 모두 실패하면 ORA-3121 메세지가 나옵니다.
-----
현상 : ORA-6108
원인 : 1.부적절한 machine, 또는 machine는 맞지만 틀린 포트를 지정할 때 발생
2.TCP/IP 레이어는 모든 연결 요구를 Listener의 소켓 큐에 넣을 수 없을 경우 발생
3.네트워크가 아주 혼잡하고 호스트에 도달하려는 중에 시간이 종료할 경우
조치 : 1.클라이언트에서 호스트 Machine에 대해 ping을 실행하십시요. 대부분의 PC TCP/IP업체는
"ping" 유틸리티를 제공합니다. 클라이언트 Machine에서 다음을 입력하십시요
ping <host IP address>
이 방법으로 잘 되지 않으면 아마도 호스트 machine이 down된 것입니다. IP 주소를 사용
하여 호스트에 대해 ping을 성공적으로 실행할 수 없으면, 서버의 호스트 이름을 사용하여
ping을 실행해 보십시요.
ping <hostname>
호스트 이름을 사용하여 ping을 실할 수 없으면 TCP/IP 구성을 점검하십시요. 호스트 이름
을 가지고 ping을 실행할 수 없으면, 연결 스트링에 호스트 이름을 사용하여 SQL*NET와
연결할 수 없습니다.
2.SQL*NET TCP/IP Listener가 해당 서버에서 실행중인지 점검하십시요. 서버의 UNIX프롬프트
에서 다음을 입력하면 됩니다.
ps -al|grep "orasrv"
이 때 최소한 한 행이 표시되어야 합니다. 그렇지 않으면 UNIX 프롬프트에서 "orasrv"
또는 "tcpctl start"를 입력하여 수화자를 띄우십시요. SYSADMIN 특권을 가지고 해당 기계
에 로그인해야 합니다.
3.서버쪽에서 루프백을 할 수 있는 지, 다시 말해서 PC 클라이언트에서 지정한 것과 같은
연결 스트링을 사용하여 서버의 툴을 연결할 수 있는지 점검하십시요. 예를 들면, 서버의
SQLPLUS 또는 SQLDBA를 호출하고 서버의 SQLPLUS 또는 SQLDBA 프롬프트에서 다음을 입력
하십시요.
CONNECT USERNAME/PASSWORD@t:<servername>/<portnum>:<sid>
4.루프백 성사되면 호스트 서버의 ORASRV 포트 번호를 확인하십시요. (대부분의 기계에서
SERVICE 파일은 /etc 디렉토리에 있습니다.) 또한 "tcpctl" 유틸리티를 사용하면 대부분의
UNIX 기계에서 ORACLE Listener를 시작하거나 멈출 수 있습니다. "tcpctl stop"로 Listener
를 종료하십시요. "tcpctl start"으로 다시 시작하십시요. 이때 시작 포트에 관한 정보가
표시됩니다.
5.이것이 성공하면 포트를 지정하지 말고 포트를 연결해 보십시요.
t:<servername>:<sid>
연결되지 않으면 클라이언트에서 SERVICE 파일을 정확하게 설정하 않았기 때문입니다.
a)WINDOWS\WIN.INI를 점검하여 [Oracle] 부분의 ORA_CONFIG 매개 변수가 어떤 구성 파일을
지시하고 는지 알아보십시요. 이폴트는 다음과 같습니다.
[Oracle]
ORA_CONFIG=C:\WINDOWS\ORACLE.INI
b)ORACLE.INI 파일을 보고 TCP_SERVICES_FILE 매개변수가 설정되었고 SERVICES 파일을 지시
하고 있는 지 확인하십시요.
c)SERVICES 파일을 보고 다음 항목이 있는 지 확인하십시요.
orasrv 1525/tcp oracle
6.또한 서버가 SQL*NET V2가 아니라 SQL*NET V1을 실행중인지 확인하십시요.
7.결 스트링의 재시도 매개변수를 증가시켜 보십시요. 재시도 횟수를 지정하는 구문은 다음과
같습니다.
t:host[/service]:SID[,buffer-size][:conn-retries]
conn-retries의 디폴트는 1입니다.
8.VAX에 연결할 경우에는 VAX config.ora 파일에 다음행이 있는지 확인하십시요.
SQLNET USERNAMEMAP*=*
이것은 VAX account가 없는 PC가 디폴트 사용자 account을 사용하여 연결 할 수 있게 해
줍니다.
-----
현상 : ORA-6110 "NETTCP: message send failure"
원인 : Windows 클라이언트의 TCP/IP사이에 버퍼 조정문제가 있을 때 발생
조치 : 1.버퍼 크기를 연결 스트링에 포함시켜 일정한 크기로 고정하는 것
t:<servername>:<sid>,<buffersize>
연결 스트링에 버퍼 크기를 포함시킨 후에도 여전히 ORA-6110이 발생하면 더 작은 값을
사용해 보십시요. WINDOWS용 SQL*NET TCP/IP의 기본 버퍼 크기는 4096입니다. 이것을
1024로 사용하면 대개 ORA-6110에러가 없어집니다.
2.서버쪽
1)서버에서 루프백을 수행할 수 있습니까? 다시 말해서 PC 클라이언트에서 지정한 것과
같은 연결 스트링을 사용하여 서버의 툴을 연결할 수 있습니까? 예를 들어 서버에서
SQLPLUS 또는 SQLDBA를 호출하고 에러가 없어집니다.
CONNECT USERNAME/PASSWORD@t:<servername><portnum>:<sid>
루프백을 실행하면 실제 문제를 더 잘 보여주는 다른 에러가 나타나는 수도 있습니다.
2)ORA-6110은 Oracle실행 파일에 사용 권한이 정확하게 설정 되어 있지 않으면 Unix 서버에
연결할 때도 발생할 수 있습니다. Oracle과 orasrv의 사용권한은 다음과 같이 설정되어야
합니다.
>chmod 6755 oracle
>chmod 6755 orasrv
이 때, Permission는 다음과 같이 설정됩니다.
-rwsr-xr-x 1 oracle dba ...size ...date oracle
-rwsr-xr-x 1 root dba ...size ...date oracle

3)ORA-6110과 틀린 네트워크 주소
TCP/IP 네트워크에서 중복 IP주소가 살아 있으면 ORA6110이 발생할 수 있습니다. 네트
워크의 모든 IP주소가 고유의 것인지 확인하십시요.
-----
현상 : ORA-6122 "NETTCP: setup failure
원인 : SQL*NET 구성이 적절하게 설정되지 않은 상태에서 WINDOWS용 SQL*NET TCP/IP를 가지고 연결
하려 할 때 발생
조치 : 1.WINDOWS\WIN.INI를 조사해 보십시요. ORA_CONFIG 매개 변수를 정의하는 ORACLE 부분이
있어야 합니다
[Oracle]
ORA_CONFIG=C:\WINDOWS\ORACLE.INI
2.ORACLE.INI(또는 ORA_CONFIG 매개변수가 지시하는 파일)을 보십시요. ORACLE_HOME이
WINDOWS용 SQL*NET TCP/IP와 다른 Oracle Windows 응용 프로그램이 설 된 디렉토리를
지시하는 지 확인하십시요. 디폴트는 다음과 같습니다.
ORACLE_HOME=\ORAWIN
3.또한 ORACLE.INI에 TCP_VENDOR를 정확하게 설정했는지도 확인하십시요.
4.경로에 C:\ORAWIN\BIN(또한 ORACLE_HOME을 설정한 BIN 디렉토리)이 있는지 확인하십시요.
DOS프롬프트에서 SET을 입력하고 <return>을 누르면 됩니다. 이명령은 경로를 보여줍니다.
5.ORAWIN\BIN 디렉토리에 SQLTCP.DLL과 SQLTCP1.DLL이 모두 있는지 확인하십시요.
6.경로의 다른 어떤 디렉토리에도 SQLTCP.DLL이 없는 것을 확인하십시요.
7.ORAWIN\BIN 디렉토리와 경로의 다른 디렉토리에 MSOCKLIB.DLL이 있는 지 확인하십시요.
또한 파일의 두 복사본을 가지고 있지 않도록 하십시요. 복사본이 둘일 경우, 이전 복사본
의 이름을 바 면 문제가 줄어들 수 있습니다.
8.WINDOWS 디렉토리에 VSL.INI 파일이 있는지 확인하십시요. 만약 없으면 ORACLE INSTALLER
를 통해 SQL*NET를 다시 입력하십시요.
-----
현상 : ORA-6136, 00000, "NETTCP: error during connection handshake"
원인 : 1.Client and Server 환경에서 간혹 SQL*NET으로 Server에 접속하려고 할 경우
2.Unix Server에서 $tcpctl stop 으로 orasrv의 Process를 정지시키려고 해도 아무런 반응
없이 Holding되는 경우가 발생
조치 : 1.TCPCTL Utility를 이용하여 다음의 Option을 부여하여 Start하는 방법.
$tcpctl start listen=30 timeout=30 forkon listen=<queue size>이며, 청취자 열의
크기를 지정.
timeout=<seconds>이며, 지정된 시간에 orasrv와의 응답 확인 시간을 나타냄.
forkon SQL*net이 orasrv process에 접근하는 방법을 나타냄.
System에 따라서 forkon option이 적용 않되는 경우도 있음.
2.Client에서 접속을 하여 사용 다가 비정상 종료(Session이 맺어진 상태에서 Client의
Power Off)를 하여 Server에 Processor가 남아 있고, orasrv를 통해 접속할 수 있는
Session의 수가 점점 줄어들 경우가 있는 데 이러한 경우에는 orasrv를(tcpctl stop or
UNIX kill command를 이용)강제로 종료 시고 다음과 같이 Start 시켜 주십시오.

#nohup tcpctl start ( Client의 비정상 종료가 Orasrv에는 영향을 미치지 않음)
또는
#orasrv (ORACLE_HOME\bin directory에서 직접 orasrv processor를 띄운다)
-----
현상 : ORA-06502 : PL/SQL : 값(수치) 오류입니다.
원인 : DB Column과 Host variableㅇ의 길이가 맞지 않은 경우.
조치 : DB Column과 Host variableㅇ의 길이를 확인하고 길이를 동일하게 한다.
-----
현상 : ORA-06533: Subscript beyond count
원인 : VARRAY는 default 로 3개의 element 이상을 가져 올수 없기 때문.
조치 : EXTEND method를 이용하여 해결할 수 있다.
-----
현상 : ORA-06571
원인 : SQL문 안에서 Stored function을 call하여 사용하는 경우 발생.
조치 : 기본적으로 stored function이나 procedure, package에서의
DML 문장의 사용은 보장이 되는 기능이나, sql list에서의 stored function의
사용은 몇 가지 제약 조건을 가지고 수행이 가능합니다.
-----
현상 : ORA-1119: error in creating database file
ORA-7515: sfccf UIC GROUP <= MAXSYSGROUP - file operations not allowed
원인 : VMS에서만 발생하는 에러로 DATAFILE을 생성하려는 Directory의 Owner가 DBA user가 아닐때 발생.
조치 : Datafile을 생성하려는 Directory의 Owner를 Oracle DBA user로 변경시켜 주어야 한다.
-----
현상 : ORA-9241, ORA-9301
원인 : 개발툴이 해당 툴 또는 SQL*NET에 필요한 메세지 화일을 찾을 수 없을 때 발생
조치 : ORACLE.INI 파일에 LOCAL = <V2 service name>을 추가한다. 만일 ORACLE.INI 파일에 LOCAL
파라미터를 추가한 후에도 계속 ora-9301 에러가 계속 발생한다면 autoexec.bat 파일에 SET
CONFIG = <PATH> \ORACLE.INI를 추가한다.
[주의 1]CONFIG가 ORACLE.INI를 지시하도록 설정하면 나중에 다시 설치할 문제가 발생할 수
있다. 그럴 때는 AUTOEXEC.BAT 에서 SET CONFIG 행을 삭제하고 다시 Booting 한후
설치를 시작한다.
[주의 2]MS ACCESS를 이용하여 ORACLE의 데이타를 질의할 경우는 환경변수를 다음과 같이
설정한다.
SET CONFIG_FILES = <path> \ORACLE.INI
[주의 3]SET 다음의 CONFIG 나 CONFIG_FILES 은 반드시 대문자 이어야 한다.
-----
현상 : ORA-9352
원인 : nt 에서 service 의 problem 발생.
조치 : 1.background services and processes 를 띄우기
dos>oradim80 -startup -sid SID -starttype srvc,inst -usrpwd password -pfile filename
2.여러 개의 instance 를 띄우고자 하는 경우
- ORACLE_SID 를 setting 한다.
c:\> set oracle_sid =sid
- server manager 실행
c:\>svrmgr30
svrmgr>connect internal/passwd
-----
현상 : ORA-12004/ORA-12034
원인 : master table의 snapshot log가 있는 table에 대해서, snapshot이 추가로
생성되고 나면 snapshot을 생성하기 시작한 시간과, 기존의 snapshot이 log를
refresh해간 시간을 비교하여 새로운 snapshot 생성시작 시간이 더 빠르면
ora-12004가 발생
조치 : 생성하고자 하는 snapshot에 대한 master table의 다른 snapshot들을 refresh하지 못하도록 하거나, refresh하지 않는 시간에 새로운 snapshot을 생성하여야 한다.
refresh 못하도록 막는 방법으로는 일시적으로 snapshot job을 broken시킨 후 snapshot이 생성된 후 다시 broken을 false로 하면 된다.
-----
현상 : ORA-12154
원인 : tnsnames.ora 파일의 Alias처럼 정의된 Connect String으로 사용하는 db_alias를 찾지 못할 경우 발생
-----
현상 : TNS-12203 "TNS:unable to connect to destination"
원인 : 1.WINDOWS용 TCP/IP 어댑터를 설치하지 않은 상태에서 연결하려 할
2.TNS-12203 에러는 WINDOWS용 ORACLE SQL*NET소프트웨어가 ORACLE 홈 디 렉토리를 찾을 수
없다는 의미일 수 있습니다.
3.TNSNAMES.ORA가 ORACLE 홈 디렉토리 아래의 NETWORK\ADMIN에 있는지 확인하십시요.
4.서버쪽에서 실행중인 SQL*NET V2 TCP/IP Listener가 없어도 TNS-12203이 발생
5.연결할 SERVICES 이름에 대해 CONNECT DESCRIPTOR에 정확한 ADDRESS 매개변수를 지정했는지
확인하십시요.
6.JSB VSL 소켓이 초기화되지 않으면 TNS-12203 이 발생할 수 있습니다.
7.TNS-12203에 이어 실제 문제가 무엇인지 더 자세하게 나타내 주는 또 다른 에러가 발생할 수
있습니다.
조치 : 1.SQL*NET TCP/IP V2는 SQL*NET V2와 V2 TCP/IP 어댑터 등 두가지 제품으로 구성됩니다.
이들은 별도의 두 키트로 되어 있는데, 반드시 두 키트를 모두 설치해야 합니다.
2.WIN.INI파일의 ORACLE 부분에 다음 항목이 있는지 확인하십시요.
[ORACLE]
ORA_CONFIG=C:\WINDOWS\ORACLE.INI
WINDOWS디렉토리가 C:\WINDOWS가 아니면, 위 행의 C:\WINDOWS 부분을 그 이름으로 바꾸십시요
그런 다음, ORACLE 소프트웨어를 다시 설치하십시요. ORACLE.INI 파일이 있으면 ORACLE.INI
파일에 다음 행이 있는지 확인하십시요.
ORACLE_HOME=C:\ORAWIN
ORACLE 홈 디렉토리가 C:\ORAWIN이 아니면 위 행의 C:\ORAWIN 부분을 이름으로 바꾸십시요.
3.ORACLE 홈 디렉토리는 ORACLE.INI(또는 WIN.INI의 ORA_CONFIG매개변수가 지시하는 파일)의
ORACLE_HOME 에 의해 정의됩니다.
4.서버쪽에서 실행중인 SQL*NET V2가 있는지 확인하십시요. 서버쪽에서 Listener Control 유틸
리티(LSNRCTL)를 사용하면 서버의 V2 Listener가 실행중인지 확인할 수 있습니다. 서버에서
"LSNRCTL STATUS"명령을 실행하십시요. Listener Control이 유틸리티 대해서는 SQL*NET
Administrator's Guide를 참조하십시요.
5.정확한 ADDRESS 매개변수를 사용중인지 확인하는 방법은, WINDOWS 클라이언트에서 사용 할 것
과 같은 ADDRESS 매개 변수를 가진 TNSNAMES.ORA를 사용하여 서버에서 루프백을 해 보는 것
입니다. 루프백을 수행한다는 것은 데이타베이스와 같은 기계에서 SQL*DBA 등을 호출하고
연결 스트링을 지정함으로써 SQL*NET V2를 통해 연결한다는 뜻입니다.
6.문제를 해결하려면 다음 사항을 점검하여 JSB VSL 레이어가 정확하게 초기화되었는지 확인
하십시요.
1)ORACLE.INI 파일(또는 WIN.INI의 ORA_CONFIG 매개변수가 지시하는 파일)의 업체키 매개
변수 TCP_VENDOR가 정확하게 설정되었는 지 확인하십시요
2)ORACLE_HOME\BIN 디렉토리에 MSOCKLIB.DLL이 있는지 확인하십시요.
3)ORACLE_HOME\BIN 디렉토리에 선택된 JSB 업체 특유의 DLL이 있는지, 또는그 JSB 업체 특유
의 TSR 파일이 실행되는 지 확인하십시요.
4)WINDOWS 홈 디렉토리에 VSL.INI 파일이 있는 지 확인하십시요.
7.화면에서 다른 에러가 보이지 않으면 ORACLE_HOME\NETWORK\LOG 디렉토리의 SQLNET.LOG 파일을
점검하십시요.
-----
현상 : TNS-12533
원인 : TNSNAMES.ORA에서 기술자의 ADDRESS 부분에 프로토콜 CONNECT DESCRIPTOR의 매개 변수가 틀릴
때 발생
조치 :
-----
현상 : ORA-12541: TNS:no listener
원인 : listener가 떠 있지 않은 경우에 발생.
조치 :
-----
현상 : TNS-12545 "TNS:name lookup failure
원인 : TNSNAMES.ORA에서 기술자의 ADDRESS 부분에 프로토콜 CONNECT DESCRIPTOR의 매개 변수가 틀릴
때 발생TCP/IP 프로토콜 어댑터를 가진 SQL*NET V2를 통해 툴에서 연결하려는 데 TCP/IP
프로토콜 어댑터가 TNSNAMES.ORA 파일의 ADDRESS 부분에 제공된 호스트 이름을 분석할 수 없을
때 발생
-----
현상 : ORA-01034: ORACLE not available
ORA-27101: shared memory realm does not exist
원인 : OPENINFO의 DB에 접속하는 계정이 존재하지 않은 경우.
조치 : DB에 접속하는 계정을 확인하여 OPENINFO의 DB 접속계정을 재설정 해야됨.
1.$ORACLE_HOME/bin directory의 "oracle"과 "orasrv" (orasrv가 없는
경우에는 "tnslsnr"을 확인해 보아야 한다.)의 permission과 ownership
을 check.
2.file system이 no set uid로 mount되어 있는지 확인.
3.oracle user의 "umask"를 확인.
4.$ORACLE_HOME/bin 에 존재하는 실행모듈의 ownership 을 확인.
5.모든 oracle file이 dba group으로 되어 있는지 확인.
6.ORACLE_HOME의 path에 존재하는 모든 directory가 755 mask로 setting
되어 있는지 확인.
-----
현상 : 0509-036,0509-022,0509-026,ORA-12547
원인 : 1.Oracle 계정이 아닌 일반 계정으로 unix에 접속하여 svrmgrl을 수행 시 발생.
2.$ORACLE_HOME/bin/oracle 실행 화일에 대한 permission이 적당하지 않을 수 있고,
unix 계정의 .profile 또는 .login 화일에 ORA_NLS33 파라미터를 셋팅하지
않았기 때문에 발생
조치 : 1.$ORACLE_HOME/bin/oracle 화일의 sticky bit가 제대로 셋팅되었는지 확인.
2.ORA_NLS33 파라미터가 제대로 셋팅되어 있는지 확인.
user가 오라클 database에 login할 때, oracle 실행 프로그램을 사용하여
오라클 계정으로 shadow process를 생성한다.
-----
현상 : ORA-24777: use of non-migratable database link not allowed.
원인 : Remote database를 사용하는데 Oracle이 dedicator server로 설치된 경우 발생(DB-Link사용할 경우)
조치 : Remote database를 사용하여 transaction를 보장 받을려면 Oracle을 MTS mode로 설치되어야 한다.
-----
현상 : ORA-29701(OGMS관련 ORACLE ERROR)
원인 : 1.오라클에서 GMS에 접속할 수 없을 경우 발생한다.
2.lmon( GMS client )이 communication file의 위치를 찾지 못할 경우 발생한다.
3.기타 발생 원인은 GMS에 틀린 internal function(skgxn)이 사용되거나
GMS가 local request에 대한 서비스를 할 수 없거나 CM subsystem에 문제가 있을
경우 등
조치 : 1.Oracle이 startup 될 때, GMS가 실행되지 않고 있을 때 발생한다. 이와
같은 경우에는 'ogmsctl status' 명령을 상용하여 GMS가 startup되었는지 확인
하여야 한다.
2.기본적으로 사용하는 디렉토리인 /tmp/.ogms를 사용하지 않을 경우 GMS home이
지정되어야 한다. OGMS home directory를 별도로 지정하여 사용할 경우에는
init.ora 파라미터 파일에서 ogms_home 파라미터 값을 지정해 주어야 한다.
-----
현상 : ORA-29702 ERROR(OGMS관련 ORACLE ERROR)
원인 : 1.오라클에서 GMS에 접속할 수 없을 경우 발생한다.
2.lmon( GMS client )이 communication file의 위치를 찾지 못할 경우 발생한다.
3.기타 발생 원인은 GMS에 틀린 internal function(skgxn)이 사용되거나
GMS가 local request에 대한 서비스를 할 수 없거나 CM subsystem에 문제가 있을
경우 등
조치 : GMS 서비스에 예상치 못한 에러가 발생했을 경우 로그에 남게 된다. GMS가 실행
중인지를 확인해 보고, 내부 에러로 인해 GMS가 스스로 shutdown 되었다면
daemon file에 기록된 트레이스 정보를 살펴보아야 한다.
-----

>oerr ora n   --> 에러 발생시 다음 명령은 치면 오라클에서 자세한 설명을 해준다.(path가 잡혀있어야 함)


출처 : http://www.databaser.net/oracle/ora_error.txt

* DestinationDirs section *

01     SourceDrive:\pathname (the directory from which the INF file was installed)
10     Windows directory. ( =>  %windir% )
11     System directory. ( =>  %windir%\system32 ) cf.Win9x/Me => %windir%\system
12     Drivers directory. ( =>  %windir%\system32\drivers )
17     INF file directory.
18     Help directory.
20     Fonts directory.
21     Viewers directory.
23     Color directory (ICM) (not used for installing printer drivers)
24     Root directory of the system disk. ( ex =>  C:\ )
25     Shared directory.
30     Root directory of the boot disk. ( "ARC system partition".  dirid 24와 다를 수도 있다.)
50     System directory for NT-based operating systems. ( =>  %windir%\system )
51     Spool directory (not used for installing printer drivers – see Printer Dirids)
52     Spool drivers directory (not used for installing printer drivers)
53     User profile directory
54     Directory where ntldr.exe and osloader.exe are located (NT-based systems only) 
55     Print processors directory (not used for installing printer drivers)
-1     Absolute path 


* special shell folders. (dirid 16384 ~ 32767)

16406     All Users\Start Menu 
16407     All Users\Start Menu\Programs 
16408     All Users\Start Menu\Programs\Startup
16409     All Users\Desktop
16415     All Users\Favorites
16419     All Users\Application Data
16422     Program Files
16427     Program Files\Common
16429     All Users\Templates
16430     All Users\Documents

16437     All Users\Documents\My Music
16438     All Users\Documents\My Pictures
49000     %windir%\system32\dllcache

16384     User\Desktop   ( =  16385 , 16387 , 16388 , 16394 16396 16399 16413 16414 )
16386     User\Start Menu\Programs
16389     User\My Documents
16390     User\Favorites
16391     User\Start Menu\Programs\Startup
16392     User\Recents
16393     User\SendTo
16395     User\Start Menu
16397     User\My Documents\My Music
16398     User\My Documents\My Video
16410     User\Application Data
16411     User\PrintHood
16412     User\Local Settings\Application Data

<예문>
[DestinationDirs]
Add_File   = 12               ;  12  와  10,system32\drivers 는 같은 경로다.
Add_File   = 16422,Test    ;  => C:\Program Files\Test
%11%\aic78xx.sys        ; dirid 로 path 연결시에는 dirid 를 % 로 감싸준다.
; 해당 폴더가 존재하지 않으면 새로 생성된다.
; 공백이 포함된 폴더명은 Strings 섹션에 임의의 문자열로 지정후  %문자열%  형식으로 사용.

테이블 선언시 자동 증가를 원하는 필드에

IDENTITY( 시작값, 증가값 )

옵션을 주시면 됩니다.
그리고 insert시에는 자동 증가 필드를 제외한 다른 필드만 값을 설정할 수 있습니다.
* 테이블 생성 시가 아니라, 생성이후에 자동 증가를 적용하시려면 그 필드가 NOT NULL 정의된 정수형 필드만 가능합니다.

CREATE TABLE ex_table
(
  notice_num  INT NOT NULL IDENTITY(1,1),
  title             VARCHAR(100)
)


 * 문자열 검사를 할 때 ==과 Equals메서드 중 누가 더 빠를까요?..

* 저번에 본 봐와 같이 ==(IL : op_Equality)에는 12개의 메서드가 사용되지만

* Equals 매서드는 2 가지만 사용되더군요.

* 따라서 문자열 비교할 때는 Equals메서드를 사용해 비교하세요.


using System;


namespace EqualsVs__

{

  /// <summary>

   /// Class1에 대한 요약 설명입니다.

   /// </summary>

   class Class1

   {

       /// <summary>

       /// 해당 응용 프로그램의 주 진입점입니다.

       /// </summary>

       [STAThread]

       static void Main(string[] args)

       {

           string strCompared = "문자열";


           //IL_000c:  call       bool [mscorlib]System.String::op_Equality(string, string)

           //사용 메서드 수 : 12개

           //시간 : 7453.4

           if (strCompared == "문자열")

               Console.WriteLine("True");


           // IL_0023:  callvirt   instance bool [mscorlib]System.String::Equals(string)

           //사용 메서드 수 : 2개

           //시간 : 37.9

          if (strCompared.Equals("문자열"))

               Console.WriteLine("True");

       }

   }

}

덧붙여서.. int,double... 의 실수와 연관있는형은 ==가 훨빠릅니다. 단 스트링비교는 반드시 equal 로 하시는 습관을 들이십시요. 얼마안된다 안된다 생각하실수도 있겠지만.. 저거 하나가 여러게 모이면 확연히 표가 납니다...

- 출처 :  KNUG (한국 닷넷 사용자 모임; Korea .NET User Group)
- 출처 2 : http://cafe.daum.net/aspdotnet

* 문자열이 있는지 검사할 때 흔히 if (문자열개체 != "")나
* if (문자열개체 != Stirng.Empty)를  쓰는데 이럴 경우 불필요한 오버헤드가 생기지만,
* Length 속성은 개체가 생성될때 설정되므로
* if (문자열개체.Length != 0 )로 해서 값만 비교해서 보다 빠르게 검사할 수 있습니다.

using System;

namespace StringEmptyVSStringLength
{
  /// <summary>
   /// Class1에 대한 요약 설명입니다.
   /// </summary>
   class Class1
   {
       /// <summary>
       /// 해당 응용 프로그램의 주 진입점입니다.
       /// </summary>
       [STAThread]
       static void Main(string[] args)
       {
          string notEmptyString = "값이 있는 문자열";

           // IL_000c:  call       bool [mscorlib]System.String::op_Inequality(string, string)
          if (notEmptyString != String.Empty)
           {
           }

          //IL_0014:  callvirt   instance int32 [mscorlib]System.String::get_Length()
           if (notEmptyString.Length != 0)
           {
           }
       }
   }
}

IL 코드로는 1가지 명령어지만

"if (notEmptyString != String.Empty)"에서는 12가지 내부 개체의 메서드를 사용해 비교하려는 양쪽의 문자열을 정렬하고 서로 일일히 비교하지만, i"f (notEmptyString.Length != 0)"에서는 단순이 변수에 값이 0이냐만 비교하기 때문에 속도가 빠를수 밖에 없죠.

실행해 시간을 검사하면 아래와 같은 차이를 보입니다. 단위는 (Microseconds)
             
742.4          if (notEmptyString != String.Empty)
0.7             if (notEmptyString.Length != 0)


- 출처 :   KNUG (한국 닷넷 사용자 모임; Korea .NET User Group)
- 출처 2 : http://cafe.daum.net/aspdotnet

스레드 사용

Greg Ewing
Clarity Consulting Inc.

요약: 기사에서는 스레딩의 다른 모델(단일, 아파트 자유) 모델의 사용에 대해 설명합니다. 스레드를 이용하는 응용 프로그램을 작성하는 도움을 있도록 스레드를 사용하는 C# 코드 샘플도 소개합니다. 또한 다중 스레딩 코드에 포함된 중요한 문제에 대해서도 설명합니다(9페이지/인쇄 페이지 기준).

목차

소개
스레딩에 대한 배경 지식
예제 응용 프로그램
다중 스레드 코드의 문제
결론

소개

다중 스레드 MSMQ(Microsoft Message Queuing) 트리거 응용 프로그램을 작성하는 일은 일반적으로 까다로운 작업이었습니다. 그러나 .NET Framework 스레딩 메시징 클래스의 도입으로 어느 때보다 쉬워졌습니다. 클래스를 사용하면 .NET Framework 대상으로 하는 모든 언어로 다중 스레드 응용 프로그램을 작성할 있습니다. 이전에 Microsoft Visual Basic 같은 도구는 스레딩에 대한 지원이 매우 제한되어 있었습니다. 따라서 C++ 사용하여 다중 스레드 코드를 작성하거나 Visual Basic에서 여러 프로세스나 ActiveX DLL 구성되는 이상적이지 않은 솔루션을 작성하거나 또는 다중 스레딩을 완전히 무시하는 밖에 없었습니다. .NET Framework에서는 어떤 언어를 사용하는지에 관계없이 풍부한 다중 스레드 응용 프로그램을 작성할 있습니다.

기사에서는 Microsoft 메시지 대기열의 메시지를 수신하고 처리하는 다중 스레드 응용 프로그램을 작성하는 프로세스를 단계적으로 소개하며, 특히 System.Threading System.Messaging이라는 가지 네임스페이스에 초점을 둡니다. 샘플 코드는 C#으로 작성되어 있지만 원하는 다른 언어로 쉽게 변환할 있습니다.

스레딩에 대한 배경 지식

Win32 환경에서 스레딩의 기본 모델은 단일, 아파트 자유 가지입니다.

단일 스레딩

처음에 작성한 응용 프로그램은 아마 응용 프로그램의 프로세스에 해당하는 스레드만 포함된 단일 스레드였을 것입니다. 프로세스는 해당 응용 프로그램의 메모리 공간을 차지하는 응용 프로그램의 인스턴스로 정의할 있습니다. 대부분의 Windows 응용 프로그램은 단일 스레드에서 모든 작업을 수행하는 단일 스레드 응용 프로그램입니다.

아파트 스레딩

아파트 스레딩은 단일 스레드보다 복잡한 스레딩 모델입니다. 아파트 스레딩으로 표시된 코드는 자체의 아파트로 제한된 고유 스레드에서 실행될 있습니다. 스레드는 처리 시간 동안 일어날 프로세스에서 소유하는 엔터티로 정의할 있습니다. 아파트 스레딩 모델에서 모든 스레드는 기본 응용 프로그램의 메모리에서 각각의 하위 섹션 내에서만 작동합니다. 모델에서는 코드의 여러 인스턴스를 동시에 그리고 독립적으로 실행할 있습니다. 예를 들어 .NET 이전의 Visual Basic에서는 아파트 스레드 구성 요소와 응용 프로그램을 만드는 것으로 제한되어 있었습니다.

자유 스레딩

자유 스레딩은 가장 복잡한 스레딩 모델입니다. 자유 스레딩 모델에서는 동시에 여러 스레드가 같은 메서드와 구성 요소로 호출됩니다. 아파트 스레딩과 달리 자유 스레딩은 분리된 메모리 공간에 제한되지 않습니다. 예를 들어 응용 프로그램에서 매우 비슷하지만 독립적인 수학 계산을 대량으로 실행해야 하는 경우에 자유 스레드 개체를 사용할 있습니다. 경우 같은 코드 인스턴스를 사용하여 계산을 실행하는 여러 스레드를 만듭니다. Visual Basic 6.0 같은 언어에서는 이와 같은 작업이 거의 불가능하므로 자유 스레드 응용 프로그램을 작성한 경험이 있는 응용 프로그램 개발자는 아마 C++ 개발자뿐일 것입니다.

스레딩 모델 작업

스레딩 모델에 대한 개념의 이해를 돕는 예로 집에서 다른 집으로 이사하는 일을 있습니다. 단일 스레드 방법은 포장에서 상자 운반과 풀기까지의 모든 일을 직접하는 것이라고 있습니다. 아파트 스레딩 모델로 작업하는 경우는 절친한 친구 몇에게 도움을 청하는 것과 같습니다. 친구는 각기 다른 방에서 일하고 다른 방에서 일하는 사람을 도울 없습니다. 그들은 각자의 공간과 이삿짐을 맡습니다. 자유 스레드 방법을 선택하는 경우, 친구들에게 도움을 요청하는 것은 아파트 스레딩 모델과 동일하지만 친구들이 모두 어느 시간이나 어느 방에서든 함께 이삿짐을 꾸릴 있다는 점이 다릅니다. 비유에서 집은 모든 스레드가 작동하는 프로세스이고 친구는 코드의 인스턴스이며 이삿짐은 응용 프로그램의 리소스와 변수입니다.

위의 예에서는 모델의 장점과 단점을 보여 줍니다. 아파트 스레딩은 구성 요소의 여러 인스턴스가 작동하므로 단일 스레딩보다 빠릅니다. 자유 스레딩에서는 모든 일이 동시에 일어나고 모든 리소스가 공유되므로 어떤 경우에는 아파트 스레딩보다 빠르고 훨씬 효율적입니다. 그러나 여러 스레드에서 공유 리소스를 변경하는 경우 문제가 일어날 있습니다. 사람이 상자를 사용해 부엌 물건을 다음 다른 친구가 와서 같은 상자에 침실 물건을 포장하는 경우를 생각해 보십시오. 번째 친구는 상자에 '부엌'이라는 레이블을 붙였는데 친구가 위에 '침실'이라는 레이블을 붙입니다. 결국 짐을 때는 부엌 물건을 침실에서 풀게 것입니다.

예제 응용 프로그램

단계로 예제 응용 프로그램의 디자인을 검토합니다. 응용 프로그램에서는 여러 스레드를 만들고 스레드는 MSMQ 대기열의 메시지를 수신합니다. 예제에서는 기본 Form 클래스와 사용자 지정 MQListen 클래스의 가지 클래스를 사용합니다. Form 클래스는 사용자 인터페이스를 처리하는 것과 아울러 작업자 스레드를 만들고 관리하고 소멸시킵니다. MQListen 클래스에는 메시지 대기열 항목을 비롯해 작업자 스레드를 실행하는 필요한 모든 코드가 포함됩니다.

다중 스레드 코드의 문제

샘플 코드 작업을 완료했으므로, 이제 다중 스레드 응용 프로그램을 작성하는 필요한 도구를 가지게 되었습니다. 스레딩은 응용 프로그램의 성능과 확장성을 극적으로 개선할 있습니다. 이런 강력함과 더불어 스레딩의 위험에 대해서도 알고 있어야 합니다. 어떤 경우에는 스레드 사용으로 응용 프로그램에 해를 끼칠 있습니다. 스레드로 인해 작업이 다운되거나 예상치 못한 결과가 일어날 있으며 심지어 응용 프로그램이 응답을 중지할 수도 있습니다.

스레드가 여러 개인 경우 스레드 서로가 특정 지점에 도달하거나 종료할 때까지 대기하고 있지 않은지 확인합니다. 제대로 수행하지 않으면 스레드가 서로 대기하고 있으므로 아무 스레드도 종료되지 않는 교착 상태를 초래할 있습니다.

여러 스레드에서 쉽게 공유될 없는 리소스(: 플로피 디스크 드라이브, 직렬 포트 또는 적외선 포트) 액세스해야 하는 경우 스레드 사용을 방지하거나 synclock 또는 mutex 같은 고급 스레딩 도구를 사용하여 동시성을 관리할 있습니다. 스레드가 리소스 하나를 동시에 액세스하려 하면 스레드에서는 리소스를 얻을 없고 데이터 손상이 일어납니다.

스레딩의 다른 일반적인 문제는 경쟁 조건입니다. 스레드가 파일에 데이터를 쓰는 동안 다른 스레드에서 해당 파일을 읽고 있는 경우 어떤 스레드가 먼저 종료할지 없습니다. 문제는 스레드가 파일경쟁 조건이라고 합니다. 읽는 스레드가 쓰는 스레드보다 앞서는 경우 없는 결과가 반환됩니다.

스레드를 사용할 모든 스레드가 다른 스레드와 별도로 완전히 작업을 마칠 있을지 여부도 생각해 보아야 합니다. 데이터를 앞뒤로 전달해야 하는 경우 데이터가 비교적 간단해야 합니다. 복잡한 개체를 전달하는 경우 개체를 앞뒤로 이동하기 위해 막대한 마샬링 비용이 들어가기 시작합니다. 이에 따라 운영 체제에서 관리하는 오버헤드가 생기고 전체 성능이 떨어집니다.

다른 문제로는 코드를 다른 개발자에게 넘겨주는 따른 전환 비용이 있습니다. .NET으로 스레딩이 훨씬 쉬워졌지만 코드를 유지 관리하는 다음 개발자가 스레딩 작업을 하기 위해서는 스레딩에 대해 알고 있어야 합니다. 그러나 점은 스레드 사용을 피해야 이유라기 보다는 적절한 코드 주석을 제공해야 이유입니다.

이런 문제들로 인해 스레딩 자체를 사용하지 않는 보다는 응용 프로그램을 디자인하고 스레드를 사용할지 여부를 결정할 모든 문제들을 기억하고 있는 것이 좋습니다. 불행히도 백서에서는 이런 문제를 방지하기 위한 방법을 설명하지 않습니다. 스레드를 사용하기로 했으나 위에서 언급한 문제가 발생한 경우 synclock이나 mutex 검토하여 문제를 해결하거나 다른 솔루션을 찾아 보십시오.

결론

여기에 있는 내용으로 스레딩을 이용하는 응용그러나 이렇게 하는 동안 관련된 문제를 기억하십시오. 스레딩은 제대로 사용하면 응용 프로그램의 성능과 확장성을 단일 스레드 응용 프로그램에 비해 훨씬 개선할 있지만, 올바로 사용하지 못하는 경우 정반대의 결과를 가져올 있으며 응용 프로그램이 불안정하게 있습니다.

출처: http://blog.naver.com/ansysda?Redirect=Log&logNo=19257436

이럴 때 :  신규 파일의 등록시 같은 이름의 파일에 대해, 파일 이력을 남기기 위해 이름만 수정해서 같은 폴더 內 존재해야 한다.

FileNameEditer 메소드가 있는 걸로 알고 있지만.......잘 모르니까.....

File.Move( OrgFilePath, NewFilePath )를 사용
OrgFilePath   = 이동해야 할 파일의 경로와 파일명
NewFilePath  = OrgFilePath를 옮길 경로

( NewFilePath 같은 경로를 쓰고 파일 이름이 변경 된 값을 준다면!  )

public static string[] GetLogicalDrives()

1. namespace : System
2. 반환 값 : 각 요소에 논리 드라이브의 이름이 들어 있는 문자열의 배열. 예를 들어 컴퓨터의 하드 드라이브가 첫 번째 논리 드라이브일 경우, 반환되는 첫 번째 요소는 "C:\"
3. 예외
- IOExceptionI/O :     오류가 발생하는 경우
- SecurityException : 호출자에게 필요한 권한이 없는 경우

using System;

class Sample
{
  public static void Main()
  {
       Console.WriteLine();
       String[] drives = Environment.GetLogicalDrives();
       Console.WriteLine("GetLogicalDrives: {0}", String.Join(", ", drives));
  }
}

결과 : "GetLogicalDrives: A:\, C:\, D:\"
출처 : MSDN


-------------------------------------------------------------------------------------

public string ReturnDir()
{

string OutputPath = string.Empty;
string innerPath = string.Empty;
string[] sar  = Environment.GetLogicalDrives();


for( int i = 0; i < sar.Length; i++ )
{

string path = sar[i].ToString() + "examplePath";

dir = new DirectoryInfo( path );
       
if( !dir.Exists ) // == false
{

path = string.Empty;
dir = null;

}
else
{

innerPath = sar[i].ToString() + "examplePath";

dir = null;

}

}


OutputPath = innerPath

return OutputPath;

}

namespace InstallService
{

public delegate void MessageHandler( string msg );

public class ActBase
{

public ActBase() //생성자
{
}


#region *. 오류관련 처리 메세지 이벤트

public event MessageHandler MessageEvent;

public void FireMessageEvent( string msg )
{

if( MessageEvent == null ) return;
MessageEvent( msg );

}

#endregion

...

#region 5. WriteAppPool : 응용프로그램 풀의 추가 (XmlDocument를 이용)
/// <summary>
/// AppPool(응용프로그램 풀)의 추가
/// </summary>
public void WriteAppPool()
{

XmlDocument xdoc = new XmlDocument();
XmlDocument AddNode = new XmlDocument();
 
OrgXmlPath = Environment.SystemDirectory + "\\inetsrv\\Metabase.xml";
XmlPath  = Application.StartupPath + "\\XmlDoc\\AppPool.xml";
BackupPath = Application.StartupPath + "\\Metabase.xml";
strReturn = string.Empty;
condition = string.Empty;

try
{

//원본 파일을 공용폴더쪽에 백업한다.
File.Copy( OrgXmlPath, BackupPath, true );

//\WINDOWS\system32\inetsrv\Metabase.xml파일을 읽어와서 준비된 AppPool.xml파일의 내용을 추가한다.
xdoc.Load( OrgXmlPath );
AddNode.Load( XmlPath );
XmlNode ImportChild = xdoc.ImportNode( AddNode.DocumentElement.LastChild, true );
xdoc.DocumentElement.AppendChild( ImportChild );
xdoc.Save( OrgXmlPath );

}
catch(Exception ex)
{

condition = "e";
strReturn = "응용프로그램 풀을 등록하는 도중 다음과 같은 오류가 발생하였습니다.\n\n";
strReturn += ex.ToString();


StringBuilder sb = new StringBuilder();    
sb.Append("[ERROR]");
sb.Append(Environment.NewLine);
sb.Append("응용프로그램 풀을 등록하는 도중 다음과 같은 오류가 발생하였습니다.");
sb.Append(Environment.NewLine);
sb.Append(ex.Message);
sb.Append(Environment.NewLine);
sb.Append(ex.Source);
sb.Append(Environment.NewLine);
sb.Append(ex.StackTrace);
sb.Append(Environment.NewLine);
this.FireMessageEvent( sb.ToString());

}

}
#endregion

...

}//end Class

}//end namespace

추가 NameSpace  
using System.Diagnostics;       [Process, ProcessStartInfo]
using System.Windows.Forms; [Application]

//Environment.SystemDirectory //system32폴더)

//Application.StartupPath  //프로그램이 실행되는 폴더

/// <summary>
/// 인터넷 정보서비스를 중지
/// </summary>
public void IIS_stop()
{

Process processCmd = new Process();
ProcessStartInfo processInfo = new ProcessStartInfo();
try
{

processInfo.FileName = "Iisreset";         //실행하려는 프로세스 이름
processInfo.Arguments = @" /stop";      //실행되는 프로세스의 인자값
processInfo.UseShellExecute = false;     //운영체제 셸의 사용여부
processInfo.CreateNoWindow = true;      //새창에서 실행 할 것인지 여부
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardError = false;
processInfo.RedirectStandardOutput = false;


processCmd.StartInfo = processInfo;

processCmd.Start();                              //프로세스의 시작
processCmd.WaitForExit();                     //프로세스가 종료 될 때 까지

                                                            무기한 대기한다.
processCmd.StandardInput.Flush();

}
catch( Win32Exception ex )
{

//Exception처리 :

Win32Exception에 해당되며, 상위 Exception으로 처리해도 된다.

}
finally
{

processCmd.Close(); //프로세스연결 종료

}

}


// 실행인자를 수집한다.

public void Example()

{

string commandLineArgs = "";
foreach(string arg in Environment.GetCommandLineArgs())
{

commandLineArgs += '"' + arg + '"' + " ";

}
commandLineArgs = commandLineArgs.Trim();

Process mainProcess = null;

try
{

ProcessStartInfo p = new ProcessStartInfo(this.executablePath);
p.WorkingDirectory = Path.GetDirectoryName(this.executablePath);
p.Arguments = commandLineArgs;
mainProcess = Process.Start(p);

}
catch(Exception e)
{
}


if(mainProcess != null)
{


try
{

mainProcess.WaitForExit(); // 실행시킨 프로세스가 종료될때까지 기다린다.

}
catch (Exception e)
{

return;

}

if (mainProcess.ExitCode == 2) // 아마도 종료코드가 0 인게 정상종료일거다....
{
}
else
{
}

}

Process p = new Process();
ProcessStartInfo pinfo = new ProcessStartInfo();


pinfo.FileName = "copy";
pinfo.Arguments = "test.txt test1.txt";


p.StartInfo = pinfo;
p.Start();


이렇게 실행을 하면 파일을 찾을 수 없다고 나옵니다.
첨에는 인자로 준 파일이 없나 했는데 실제로는 Process에서 실행하는 명령의 파일 이름은 실제 존재하는 exe 실행 파일을 의미 합니다.
제가 실행 하려고 했던 copy 명령은 실제로는 cmd.exe 파일의 내부 명령입니다.
그래서 파일을 찾을 수 없다고 하는 것입니다.
하여간 하다보니 이렇게 cmd 내장 명령을 실행 하려면 어떻게 해야 하는지도 궁금해 져서 이렇게 질문을 올립니다.


Process p = new Process();
ProcessStartInfo pinfo = new ProcessStartInfo();

p.StartInfo = pinfo;


pinfo.FileName = "cmd";

pinfo.UseShellExecute=false;

pinfo.CreateNoWindow=true;

pinfo.RedirectStandardInput=true;

pinfo.RedirectStandardError=false;

pinfo.RedirectStandardOutput=false;    


p.Start();

p.StandardInput.WriteLine(@"copy G:\Test\test.xls G:\Test\test2.xls");

p.StandardInput.Flush();


//화일이 있으면 덮어쓴다.

//  p.StandardInput.WriteLine(@"Y");

//  p.StandardInput.Flush();


p.Close(); 


저는 copy 명령을 직접 날리는 것으로 했는데,,,
아래와 같이 하니까 되네요
두가지 모두 잘 됩니다.
CMD 명령어의 옵션 값으로 해결을 했습니다.


pinfo.FileName = "cmd";

pinfo.Arguments = "/C copy c:\\code39.txt com1:";


출처 :데브피아

추가 정보
한 번에 하나씩 셀을 채우지 않고 여러 셀 범위를 채우려면 Range 개체의 Value 속성을 2차원 배열로 설정하면 됩니다. 마찬가지로 Value 속성을 사용하여 한 번에 여러 셀에 대한 2차원 배열 값을 가져올 수 있습니다. 다음 단계에서는 2차원 배열을 사용하여 데이터를 설정하고 검색하는 과정을 보여 줍니다.
Microsoft Excel용 자동화 클라이언트 빌드

1. Microsoft Visual Studio 2005 또는 Microsoft Visual Studio .NET를 시작합니다.

2. 파일 메뉴에서 새로 만들기를 누르고 프로젝트를 누릅니다. Visual C# 프로젝트 형식에서 Windows 응용 프로그램을 선택합니다. 기본적으로 Form1이 만들어집니다.

3. Visual Studio 2005의 경우 Microsoft Excel 11.0 Object Library에 대한 참조나, Visual Studio .NET의 경우 Microsoft Excel Object Library에 대한 참조를 추가합니다. 해당 참조를 추가하려면 다음과 같이 하십시오.

a.  프로젝트 메뉴에서 참조 추가를 누릅니다.
b.  COM 탭에서 Microsoft Excel Object Library를 찾아 선택을 누릅니다.

Visual Studio 2005의 경우 COM 탭에서 Microsoft Excel 11.0 Object Library를 찾습니다.

참고 Microsoft Office 2003에는 PIA(기본 Interop 어셈블리)가 포함되어 있습니다. Microsoft Office XP에는 PIA가 포함되어 있지 않지만 PIA를 다운로드할 수 있습니다. Office XP PIA에 대한 자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조하십시오.
328912 (http://support.microsoft.com/kb/328912/) Microsoft Office XP PIA를 다운로드할 수 있다 
c.  참조 추가 대화 상자에서 확인을 눌러 선택한 내용을 적용합니다. 선택한 라이브러리에 대해 래퍼를 생성할 것인지 묻는 메시지가 나타나면 예를 누릅니다.

4. 보기 메뉴에서 도구 상자를 선택하여 도구 상자를 표시합니다. 단추 두 개와 확인란 하나를 Form1에 추가합니다.

5. 확인란의 이름 및 텍스트 속성을 FillWithStrings로 설정합니다.

6. Button1을 두 번 누릅니다. 해당 폼에 대한 코드 창이 나타납니다.

7. 코드 창에서


private void button1_Click(object sender, System.EventArgs e)
{
}
   
위의 코드를 아래와 같이 바꿉니다.      

//Declare these two variables globally so you can access them from both
//Button1 and Button2.
Excel.Application objApp;
Excel._Workbook objBook;

private void button1_Click(object sender, System.EventArgs e)
{

Excel.Workbooks objBooks;
Excel.Sheets objSheets;
Excel._Worksheet objSheet;
Excel.Range range;

try
{

// Instantiate Excel and start a new workbook.
objApp = new Excel.Application();
objBooks = objApp.Workbooks;
objBook = objBooks.Add( Missing.Value );
objSheets = objBook.Worksheets;
objSheet = (Excel._Worksheet)objSheets.get_Item(1);

//Get the range where the starting cell has the address
//m_sStartingCell and its dimensions are m_iNumRows x m_iNumCols.
range = objSheet.get_Range("A1", Missing.Value);
range = range.get_Resize(5, 5);

if (this.FillWithStrings.Checked == false)
{

//Create an array.
double[,] saRet = new double[5, 5];

//Fill the array.
for (long iRow = 0; iRow < 5; iRow++)
{

for (long iCol = 0; iCol < 5; iCol++)
{
//Put a counter in the cell.
saRet[iRow, iCol] = iRow * iCol;
}

}

//Set the range value to the array.
range.set_Value(Missing.Value, saRet );

}

else
{

//Create an array.
string[,] saRet = new string[5, 5];

//Fill the array.
for (long iRow = 0; iRow < 5; iRow++)
{

for (long iCol = 0; iCol < 5; iCol++)
{
//Put the row and column address in the cell.
saRet[iRow, iCol] = iRow.ToString() + "|" + iCol.ToString();
}

}

//Set the range value to the array.
range.set_Value(Missing.Value, saRet );

}

//Return control of Excel to the user.
objApp.Visible = true;
objApp.UserControl = true;

}

catch( Exception theException )
{

String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat( errorMessage, theException.Message );
errorMessage = String.Concat( errorMessage, " Line: " );
errorMessage = String.Concat( errorMessage, theException.Source );

MessageBox.Show( errorMessage, "Error" );

}

}
   
참고 Visual Studio 2005에서는 코드를 변경해야 합니다. 기본적으로 Visual C#에서는 Windows Forms 프로젝트를 만들면 해당 프로젝트에 폼 하나가 추가됩니다. 이 폼의 이름은 Form1입니다. 폼을 나타내는 두 개의 파일 이름은 각각 Form1.cs와 Form1.designer.cs입니다. 코드는 Form1.cs에 작성합니다. Windows Forms 디자이너에서는 사용자가 도구 상자에서 컨트롤을 끌어 놓는 방법으로 수행한 모든 작업을 구현하는 코드를 Form1.designer.cs 파일에 작성합니다. Visual C# 2005의 Windows Forms 디자이너에 대한 자세한 내용은 다음 MSDN(Microsoft Developer Network) 웹 사이트를 참조하십시오.
http://msdn2.microsoft.com/ko-kr/library/ms173077.aspx (http://msdn2.microsoft.com/ko-kr/library/ms173077.aspx)

8. Form1의 디자인 보기로 돌아가서 Button2를 두 번 누릅니다.

9. 코드 창에서

private void button2_Click(object sender, System.EventArgs e)
{
}
   
위의 코드를 아래와 같이 바꿉니다.

private void button2_Click(object sender, System.EventArgs e)
{

Excel.Sheets objSheets;
Excel._Worksheet objSheet;
Excel.Range range;

try
{

try
{


//Get a reference to the first sheet of the workbook.
objSheets = objBook.Worksheets;
objSheet = (Excel._Worksheet)objSheets.get_Item(1);

}

catch( Exception theException )
{

String errorMessage;
errorMessage = "Can't find the Excel workbook.  Try clicking Button1 " + "to create an Excel workbook with data before running Button2.";

MessageBox.Show( errorMessage, "Missing Workbook?");

//You can't automate Excel if you can't find the data you created, so
//leave the subroutine.
return;

}

//Get a range of data.
range = objSheet.get_Range("A1", "E5");

//Retrieve the data from the range.
Object[,] saRet;
saRet = (System.Object[,])range.get_Value( Missing.Value );

//Determine the dimensions of the array.
long iRows;
long iCols;
iRows = saRet.GetUpperBound(0);
iCols = saRet.GetUpperBound(1);

//Build a string that contains the data of the array.
String valueString;
valueString = "Array Data\n";

for (long rowCounter = 1; rowCounter <= iRows; rowCounter++)
{

for (long colCounter = 1; colCounter <= iCols; colCounter++)
{

//Write the next value into the string.
valueString = String.Concat(valueString,
saRet[rowCounter, colCounter].ToString() + ", ");

}

//Write in a new line.
valueString = String.Concat(valueString, "\n");

}

//Report the value of the array.
MessageBox.Show(valueString, "Array Values");

}

catch( Exception theException )
{

String errorMessage;
errorMessage = "Error: ";
errorMessage = String.Concat( errorMessage, theException.Message );
errorMessage = String.Concat( errorMessage, " Line: " );
errorMessage = String.Concat( errorMessage, theException.Source );

MessageBox.Show( errorMessage, "Error" );

}

}


10. 코드 창의 맨 위로 스크롤합니다. using 지시문 목록의 끝에 다음 행을 추가합니다.

using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;
   

자동화 클라이언트 테스트
1. F5 키를 눌러 예제 프로그램을 빌드하고 실행합니다.

2. Button1을 누릅니다. Microsoft Excel이 시작되어 새로운 통합 문서가 나타나고 첫 번째 워크시트의 A1:E5 셀이 배열의 숫자 데이터로 채워집니다.

3. Button2를 누릅니다. A1:E5 셀의 데이터가 새로운 배열에 삽입되고 결과가 메시지 상자에 표시됩니다.

4. FillWithStrings를 선택하고 Button1을 눌러 A1:E5 셀을 문자열 데이터로 채웁니다.

리눅스용이라면... http://cafe.daum.net/oraclemanager 라고 여기에 있습니다.

그리고 윈도우용이라면요.. JD1.3버젼을 받기가 어려우신 가보군요.

심파일에 가보시면.. (http://simfile.chol.com ) java라고 치시면 나옵니다.

그거 다운받으시고 설치하시면 대요. 그리고 나서.. classpath 지정을 해야지요.

classpath 지정은 자바책을 참고하시구요.

윈도우용이면 그리 설치하는 방법은 어렵지 않습니다. 그리고 중간에 에러도

거의 나지를 않지요.. 하지만..오라클을 윈도우에서 사용하는 것은 극히 위험하기

때문에(보안 문제, 재부팅을 해야하는 문제등등) 리눅스를 많이 사용하고 있답니다.

저 같은 경우엔.. 한컴리눅스3을 한컴리눅스 사이트에서 다운받아서 사용하고 있구요.

거기에 오라클을 설치해서 DB설계 프로젝트를 지금 현재 진행중입니다. (여담으로
Connection manager때뮈 골치아팠찌여..)


그리고 어떻게 설치하냐면요.. 아래를 참고하세요. 저는 아래와 같은 방법으로 합니다.

어느 분의 자료인데요.. 저는 이거 가지고 해요..

-------------------------- 자료(다른 사람 자료를 조금 고쳤습니다)--------------------------

한컴리눅스3에서 설치하기.. JAVA JDK는 설치 안해도 됩니다. 오라클에서 자동으로 읽더군요.
한컴리눅스가 좋은 점이 사용자 위주로 되어있어서 초보자가 편하다는 장점이 있었습니다.
그래서 이걸로 사용하고 있지요. 물론 멀티부팅을 해야하는 경우에도 한컴리눅스는 자동으로
잘 잡아줍니다. 아주 편하죠...아래와 같이 하시구요..
중요한 것은 오라클 설치 그룹을 만들고, 유저를 생성하고, 그런 담에 아래와 같이
vi /home/oracle/.bash_profile 을 정합니다.
그리고 나서.. 설치하다가 보면 에러가 뜨는데 이것은 $ORACLE_HOME/ctx/lib/env_ctx.mk 파일을 열고
$ORACLE_HOME/ctx/lib/env_ctx.mk 파일의 1365줄로 이동합니다.거의 마지막 부분에 있으므로 가장
마지막에서 위로 찾아 올라갑니다.
INSO_LINK = -L$(CTXLIB) $(LDLIBFLAG)m 다음에 $(LDLIBFLAG)dl 을 추가하여 줍니다.
이것만 하면 됩니다. 물론 처음에는 정말 설치하기 어렵습니다. 저두 한달동안 40번을 설치를
해보았지요. 중간에 에러나서 정말 고생 많이 했지요. 하지만 아래처럼 해보니 괜찮게 되더군요.
참고하세요^^




1. OS 및 하드웨어 환경

RAM 512MB
파티션 hdb1 8GB e / ext2hdb2 1GB e /tmp ext2hdb2 1GB e swap swap

2. 설치할 프로그램 버전 및 다운로드
Oracle Oracle 9.2.0.1.0
** Oracle 9.2.0.1.0 버전은 OTN(Oracle Technology Network 에서 다운 받습니다. otn.oracle.com
모든 설치 프로그램은 /usr/local/src에 옮겨 놓습니다.

3. 설치
가) 시스템 요구사항 확인
리눅스용 오라클9i 시스템 요구사항
하드웨어 요구사항 및 명령어
최소메모리 512 MB RAM 이상#grep MemTotal /proc/meminfo
교체 공간 일반적으로 RAM 용량의 1배나 최소한 400MB RAM 이상# /sbin/swapon -s
CD-ROM 드라이브 ISO9660 포맷을 지원하는 CD-ROM
디스크 공간 오라클 9I 소프트웨어 전체를 설치하기 위해 최소 2.5GB가 필요하며, 데이터베이스를 위해서는 1GB가 추가로 필요하다.# df ?k
임시 디스크 공간 tmp directory에 최소한 400MB의 Free 영역이 필요하다. 400MB의 용량이 되지 않을 경우에는 오라클 사용자 환경변수 TEMP 와 시스템 전역변수 TMPDIR가 다른 파일시스템에 생성될 수 있다.# env | grep TEMP# env | grep TMPDIR

소프트웨어 요구사항 및 명령어
OS SUSE Linux 7.1이상, Linux Kernel 2.4.4 이상, GNU C lib 2.2# uname ?r# rpm ?qa | grep glibc
JAVA JRE ? Sun JRE 1.3.1 / JDK ? Sun JDK 1.3.1 / blackdown 1.1.8_v3 이상

나) 공유 메모리 설정
오라클사가 제공한 커널 파라미터 값에 대한 권고값
파라미터 권장값 설명
SEMMNI 100 시스템 내 세마포어 셋의 최대 개수, 동시에 사용될 수 있는 세마포어의 최대 개수를 결정한다.
SEMMNS 256 시스템 내 세마포어 전체 개수
SEMMSL 100 한 개의 세마포어 셋에 존재할 수 있는 세마포어의 최대개수.오라클 프로세스의 최대개수에 10개정도를 더한 값으로 설정한다.
(오라클 initSID.ora 파일 내의 processes 파라미터)
SEMOPM 100 시스템 내 semop를 호출할 때마다 operation의 최대 개수
SEMVMX 32767 세마포어의 최대값을 결정한다.
SHMMAX 2147483648 한 개의 공유 메모리 세그먼트의 최대 크기 (단위: 바이트)
SHMMIN 1 한 개의 공유 메모리 세그먼트의 최소 크기 (단위: 바이트)
SHMMNI 100 공유 메모리 세그먼트의 최대 개수
SHMSEG 4096 한 개의 프로세스에 연결될 수 있는 공유 메모리 세그먼트의 최대값
** 공유 메모리와 세마포어의 개수 알아보기**
[root@ora9 /]# cd /proc/sys/kernel
공유메모리
[root@ora9 kernel]# cat shmmax e SHMMAX의 설정값을 출력한다.
[root@ora9 kernel]# cat shmmni e SHMMNI의 설정값을 출력한다.
세마포어
[root@ora9 kernel]# cat sem e SEMMSL, SEMMNS, SEMOPM, SEMMNI 값
원래 공유메모리와 세마포어를 변경한 값을 적용하여 커널을 재컴파일 해야하지만 여건이 되지 않는 (필자도 커널 재컴파일 여건이 안된다.)경우 소프트웨어적으로 공유메모리와 세마포어를 변경할 수 있다.
[root@ora9 kernel]# vi /etc/sysctl.conf
다음과 같이 편집한다.

# Disables packet forwading
net.ipv4.ip_forwad = 0
# Enable source route verification
net.ipv4.conf.default.rp_filter = 1
# Disable the magic-sysrq key
kernel.sysrq = 0
kernel.shmmax = 2147483648
kernel.sem = 512 3200 100 100

다) 설치 환경설정
① Oracle 9i 압축 풀기 및 CD 굽기
오라클 사이트에서 다운 받은 파일을 /usr/local/src 폴더에 넣어둡니다.
[root@ora9 /]# cd /usr/local/src
압축을 해제합니다. (시간이 상당히 걸립니다. 느긋하게 기다립시다.)
[root@ora9 src]# zcat lnx_920_disk1.cpio.gz | cpio -idmv
[root@ora9 src]# zcat lnx_920_disk2.cpio.gz | cpio -idmv
[root@ora9 src]# zcat lnx_920_disk3.cpio.gz | cpio ?idmv
압축을 푼 파일들을 3장의 cd에 굽기 원한다면 다음과 같이 작성합니다.
[root@ora9 src]# mkisofs -r Disk1 | cdrecord -v --eject dev=0,0,0 speed=4
[root@ora9 src]# mkisofs -r Disk2 | cdrecord -v --eject dev=0,0,0 speed=4
[root@ora9 src]# mkisofs -r Disk3 | cdrecord -v --eject dev=0,0,0 speed=4
dev 번호를 알고 싶다면 다음 명령을 내리십시오.
[root@ora9 src]# cdrecord -scanbus
scsibus0:
0,0,0 0) 'ATAPI ' 'CD-R/RW 4X4X32 ' '3.LS' Removable CD-ROM
(생략)
필자의 리눅스 컴퓨터에 설치된 CD Writer는 4배속(쓰기), 4배속(재기록), 32(읽기) 이므로 스피드를 4배속으로 맞추었습니다.


⑤ 오라클 사용자와 그룹 생성
오라클 제품 설치 및 설정변경을 담당할 oinstall과 시스템 내의 오라클 데이터베이스를
관리할 dba 그룹을 생성한다.
[root@ora9 /]# groupadd oinstall
[root@ora9 /]# groupadd dba
oracle 을 사용자로 설정하고 initial group을 oinstall과 group을 dba로 그룹을 할당한다.
[root@ora9 /]# useradd -g oinstall -G dba oracle
oracle 계정의 Password를 설정한다.
[root@ora9 /]# passwd oracle
⑥ 오라클 제품이 설치될 Mount Point를 생성한다.
/opt/oracle 디렉토리를 생성하여 하위 디렉토리까지 오라클 사용자가 관리하도록 해준다.
[root@ora9 /]# mkdir /opt/oracle
[root@ora9 /]# chown -R oracle.oinstall /opt/oracle/

⑦ oracle 사용자 계정의 환경을 설정한다.(다음 내용을 빠짐없이 작성한다.)
[root@ora9 /]# vi /home/oracle/.bash_profile
# for ORACLE

export ORACLE_BASE=/opt/oracle
export ORACLE_HOME=/opt/oracle/product/920
export ORACLE_OWNER=oracle
export ORACLE_SID=ora9
export ORACLE_TERM=ansi
export DISPLAY=localhost:0.0
export TNS_ADMIN=$ORACLE_HOME/network/admin
export NLS_LANG=AMERICAN_AMERICA.KO16KSC5601
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$ORACLE_HOME/rdbms/demo
export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
export PATH=$ORACLE_HOME/JRE/bin:$ORACLE_HOME/bin:.:$PATH
export TEMPDIR=/tmp
export EDITOR=vi
export LANG=korean
# for DBA/User
umask 022


오라클 환경 설정 항목과 그에 대한 설명
설정 이름 설정 설명
ORACLE_BASE 오라클 설치 프로그램인 OUI를 저장하고 오라클 트레이스 파일 및 데이터 파일을 저장하는 디렉토리의 이름을 기록하는 오라클 환경변수 명이다.
ORACLE_HOME 현재 설치하고자 하는 오라클 데이터베이스 서버를 저장할 디렉토리명을 기록한다.
ORACLE_OWNER 오라클 제품을 컴트롤할 OS 시스템 레벨의 유저가 누구인가를 설정하는 오라클 환경변수로, 앞 단락에서 생성한 oracle 사용자를 지정한다.
LD_LIBRARY_PATH 오라클 제품을 사용할 때 사용되는 오라클 공유 라이브러리들의 경로를 나타낸다. 반드시 $ORACLE_HOME/lib를 포함하여 설정한다./
ORACLE_SID 오라클 서버 인스턴스의 이름인 Oracle System Identifier(SID)를 설정한다. 하나의 하드웨어에 여러 개의 데이터베이스 인스턴스가 존재할 수 있지만, SID는 개별 인스턴스에 대해 유일한 이름으로 명명되어야 한다.
PATH $ORACLE_HOME/bin을 포함하여 설정한다.
NLS_LANG 오라클 데이터베이스의 문자 셋을 설정한다. 여러분이 생성하게 될 데이터베이스의 문자셋과 일치해야 한다.
TNS_ADMIN Oracle Network를 구성할 때 필요한 설정파일의 위치를 지정하는 것으로, insterner.ora, tnsnames.ora, sqlnet.ora 파일들이 위치하고 있다.
ORA_NLS33 NLS_LANG 항목에 설정된 문자 셋대로 오라클 데이터베이스에서 각국의 언어 및 도량형을 제공하는 데 필요한 정보를 갖고 있는 파일들의 위치를 지정한다.
TEMPDIR 오라클 데이터베이스가 운영 중에 임시 파일들을 위치시킬 장소를 지정한다.
EDITOR SQL *Plus 상에서 edit명령어를 사용했을 때 실행할 수 있는 OS 레벨의 에디터를 지칭하는 것으로, 여러분에게 익숙할 만한 pico, vi를 설정한다.
LANG 데이터베이스의 문자 셋을 결정하는 NLS_LANG과 달리, 현재 사용자의 세션에서의 문자 셋을 결정하는 시스템 환경변수이다. 필자와 같이 ko_KR.eucKR를 설정하면 한글화된 시스템 메시지를 볼 수 있으며, 오라클에서 제공하는 모든 자바 툴에서 한글화 메시지를 바로 볼 수 있다.
DISPLAY Oracle Universal Installer 등 오라클에서 제공하는 자바로 만들어진 여러 가지 툴이 구동하기 위한 X윈도우 환경을 설정하기 위한 것으로, 사용자의 서버 명이나 IP를 설정한다.

⑧ 재부팅 합니다. (위의 공유 메모리와 세마포어 값의 변경 등을 적용하기 위함입니다.)
[root@ora9 src]# shutdown -r now

라) 설치
설치시 root계정으로 로그인 후 X-Window를 실행하고 터미널 창을 두개 띄워
위쪽 창은 root 계정으로 아래쪽 창은 oracle 계정으로 작업하도록 한다.
[root@ora9 root]# su oracle
위에서 설정한 오라클 사용자의 설정이 적용되도록 강제로 로드합니다.
[oracle@ora9 oracle]$ source $HOME/.bash_profile
다운받은 오라클 설치 프로그램의 압축을 푼 디렉토리로 이동합니다.
[oracle@ora9 oracle]$ cd /usr/local/src/Disk1
[oracle@ora9 Disk1]$ ./runInstaller

Oracle Universal Installer 가 로딩됩니다.


설치 첫 화면 입니다. “다음”을 클릭하여 계속 설치를 진행합니다.


오라클을 처음 설치할 때에만 표시되는 화면으로써, OUI 관련 파일들의 위치를 지정합니다. 사용자 환경에 ORACLE_BASE를 지정하였다면 해당 디렉토리가 표시됩니다. “확인” 버튼을 눌러 계속 설치를 진행합니다.


시스템에서 오라클을 설치하고 갱신할 수 있는 UNIX GROUP을 지정합니다.


오라클 설치 및 갱신 가능한 그룹 이름 “oinstall”을 작성하고 “다음” 버튼을 클릭합니다.



설치를 계속 하기 전에 root 권한으로 특정 파일(/tmp/orainstRoot.sh)을 실행해야 합니다.



콘솔 실행 후 root계정으로 /tmp/orainstRoot.sh 파일을 실행합니다.


이것을 실행하면 /etc/oraInst.loc 파일이 생성됩니다. 이 파일은 오라클 Inventory의 위치와
이를 다루는 유닉스 계정 그룹 명이 기록됩니다.

“계속” 버튼을 눌러 계속 설치를 진행합니다.

오라클의 원본 디렉토리를 표시하며, 사용자 환경에 설정된 ORACLE_HOME 의 이름 및
설치가 될 디렉토리가 표시된다. “다음” 버튼을 클릭하여 계속 설치를 진행한다.
만약 CD로 설치한다면 경로에 CD-ROM의 경로가 표시될 것이다.

제품을 로드 합니다.

“Oracle9i Database 9.2.0.1.0”을 선택하여 데이터베이스를 구성합니다.
“제품 언어...”를 클릭합니다.

제품언어에 한국어와 영어가 추가되어 있는지 확인합니다.
“확인” 버튼을 클릭 하여 계속 설치를 진행합니다.

설치 유형을 묻는 화면입니다. 여기서는 Enterprise Edition을 선택하여 설치합니다.
Enterprise Edition은 모든 컴포넌트가 설치 됩니다. “다음” 버튼을 클릭합니다.


“설치 유형”에서 “Database Configuration”으로 넘어가는 중간 화면 입니다.


Database Suite에서 General Purpose를 선택합니다. “다음”버튼을 클릭하여 계속 설치를 진행합니다.

l General Purpose: 범용적인 데이터베이스를 구성할 때
l Transaction Processing: OLTP성 작업이 주가 될 때
l Data Warehouse: DSS 목적으로 데이터베이스를 구성할 때
l Customized: 사용자 정의 데이터베이스를 구성할 때
l Software Only: 데이터베이스를 설치하지 않고 오라클 데이터베이스 제품만 설치할 때
“Database Configuration”에서 Database File Location”으로 넘어가는 중간 화면 입니다.

Global Database 이름을 적어 줍니다. 대개 데이터베이스 이름.네트워크 도메인 이름을 이용합니다.


개인적으로 도메인 jungyama.pe.kr을 이용하므로 ora9.jungyama.pe.kr을 작성하였습니다.
“다음”버튼을 클릭하여 계속 설치를 진행합니다.

데이터베이스 파일이 저장될 위치를 지정합니다. “다음”를 클릭하여 계속 설치를 진행합니다.


Oracle DB에서 사용할 문자 셋을 설정합니다. 이곳 설정은 $HOME/.bash_profile 의
NLS_LANG의 값과 일치해야 합니다. Default character set 이 KO16KSC5601이므로
Database Character Set을 default로 놓고 “다음” 버튼을 물러 계속 설치를 진행합니다.

설치될 목록을 확인해 보고 “설치” 버튼을 클릭하여 계속 설치를 진행합니다.
만약 구성 요소 중 변경할 사항이 있다면 “이전” 버튼을 클릭합니다.


설치가 진행되고 있는 상태 입니다. 시간이 오래 걸리니 느긋하게 기다립니다.


파일이 옮겨지고 링크 작업이 진행되고 있는 상태 입니다.
시간이 좀 걸리니 느긋하게 기다립니다.


설치가 거의 끝날 무렵 다음과 같은 오류가 납니다. 이때 어떠한 버튼도 클릭하지 않습니다.
ORACLE_HOME/ctx/lib/env_ctx.mk 파일을 엽니다.

$ORACLE_HOME/ctx/lib/env_ctx.mk 파일의 1365줄로 이동합니다.
거의 마지막 부분에 있으므로 가장 마지막에서 위로 찾아 올라갑니다.

INSO_LINK = -L$(CTXLIB) $(LDLIBFLAG)m 다음에 $(LDLIBFLAG)dl 을 추가하여 줍니다.


“재시도”버튼을 클릭하여 계속 설치를 진행합니다.


링크 오류 후 링크 작업이 계속 진행되고 있는 그림 입니다.

설치를 계속 하기전에 root 권한으로 특정 파일을 실행해야 합니다


콘솔 실행 후 root계정으로 /opt/oracle/product/9.2.0/root.sh 파일을 실행합니다.

이때 local bin directory를 묻는데, 기본값 그대로 “Enter”를 누릅니다.
시간이 조금 걸리니, 느긋하게 기다립니다.

/opt/oracle/product/9.2.0/root.sh 파일이 실행되고 난 후 화면입니다.

“OK” 버튼을 클릭하여 계속 설치를 진행합니다.

설치와 링크 작업이 거의 끝나 가는 화면입니다.
이곳까지 따라오시느라 수고 많았습니다.

구성 툴이 실행됩니다. 시간이 오래 걸리니 느긋하게 기다립니다. 만약 이 단계에서 멈춘다면 환경설정 파일(.bash_profile)의 NLS_LANG 값과 설치 시 Character Set이 일치하는지 확인 합니다.


“Oracle Database Configuration Assistant”에서 내용이 없는 창이 뜹니다.
설치상에 문제가 있는 것은 아니니 조금 기다립니다.

“Database Configuration Assistant”에서 “Oracle 인스턴스 생성 및 시작” 중 화면입니다.


“Database Configuration Assistant”에서 “데이터베이스 생성 완료 중” 화면입니다.
데이터베이스 파일을 복사하여 다시 재구성하는 것이므로 시간이 오래 걸리지 않습니다.


Database Configuration Assistant 2번째 창입니다.
SYS와 SYSTEM 계정의 보안을 위하여 암호를 변경합니다.


SYS와 SYSTEM 계정의 암호를 변경 후 “암호 관리…” 버튼을 눌러봅니다.


암호 관리 창에는 계정정보를 볼 수 있습니다. SYS, SYSTEM, DBSNMP, SCOTT 계정을 제외하고 계정이 잠겨져 있는 것을 확인 할 수 있습니다. “확인” 버튼을 클릭하여 계속 설치를 진행합니다.


“확인”버튼을 클릭하여 계속 설치를 진행합니다.


“구성 툴”에서 “Starting HTTP Server” 구성이 진행중인 화면입니다.
만약 해당 구성이 필요 없다면 “정지”버튼을 클릭하여 구성을 중지합니다.


설치가 완전히 완료 되었습니다. Oracle9i Database 설치 요약 정보가 나타나는 화면입니다.


만약 설치된 제품 중에 제거하고 싶은 요소가 있다면 위에서 “설치된 제품” 버튼을 클릭하여
제거하고 싶은 항목을 클릭 후 “제거…” 버튼을 클릭하여 제거합니다.


설치를 마치려면 “종료” 버튼을 클릭 후 “예(Y)” 버튼을 클릭하여 설치를 완전히 종료합니다.


만약 다른 구성요소를 더 설치하고 싶다면 “다음 설치” 버튼을 클릭하여 다른 요소를 더 설치 합니다.


마) Database 시작과 종료
① 오라클 데이터베이스 시작하기
Database 의 시작과 종료는 반드시!! Oracle 계정으로 수행해야 합니다.
[root@ora9 /]# su oracle
[oracle@ora9 /]$ source $HOME/.bash_profile
oracle 계정으로 로그인 후 oracle 계정의 환경설정을 reload 합니다.
(처음부터 오라클 계정으로 로그인 하였다면 이 과정은 불필요합니다.)

[oracle@ora9 /]$ sqlplus /nolog
SQL>connect / as sysdba
SQL> startup
오라클 데이터베이스를 시작하고 종료하기 위해서는 OS에서의 인증과 암호 파일을 생성하는
툴인 orapwd를 통해야 한다. 그리고 sys 스키마의 권한인 sysdba 권한과 public 스키마
권한인 sysoper 권한의 특별한 시스템 권한을 소유한 사용자이어야 한다.

· sysdba : 데이터베이스 시작/종료, 아카이브 및 복구 작업, ALTER DATABASE OPEN,
MOUNT, BACKUP, CHANGE, CHARACHER SET 절의 명령어 실행
· sysoper : 데이터베이스 시작/종료, 아카이브 및 복구 작업, ALTER DATABASE OPEN,
MOUNT, BACKUP 절의 명령어 실행

SQL> SELECT * FROM v$version;
현재의 오라클 데이터베이스 인스턴스의 버전 확인하기

② 오라클 데이터베이스 종료하기
[oracle@ora9 /]$ sqlplus /nolog
SQL> connect / as sysdba
SQL> shutdown immediate

③ oratab 파일 편집하기
오라클 데이터베이스를 /etc/rc.d/ini.d에 스크립트로 설정하여 자동으로 실행하게 하여봅시다.
[root@ora9 /]# vi /etc/oratab
다음 부분을 수정 ([SID], [ORACLE_HOME], [자동실행/종료 플래그]로 구성되어 있습니다.)
ora9:/opt/oracle/product/9.2.0.1.0:N e ora9:/opt/oracle/product/9.2.0.1.0:Y

④ Parameter 파일 링크 (xxxxxxxxxxxx은 일정치 않은 숫자 입니다.)
[root @ora9 /]# cp /opt/oracle/admin/ora9/pfile/initora9.ora.xxxxxxxxxxxx \
/opt/oracle/product/9.2.0.1.0/dbs/initora9.ora

⑤ /etc/rc.d/init.d 에 등록하기
oracle9i 스크립트를 /etc/rc.d/init.d 에 복사합니다.
[root@ora9 /]# cp /usr/local/src/oracle9i /etc/rc.d/ini.t/
oracle9i에 실행권한을 부여합니다.
[root@ora9 /]# chmod 755 /etc/rc.d/init.d/oracle9i
실행수준 2,3,4에 해당하는 데이테베이스를 실행시키기 위하여 심볼릭 링크를 한다.
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc2.d/S99oracle9i
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc3.d/S99oracle9i
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc4.d/S99oracle9i
시스템을 재부팅하거나, 재실행 할 때에 데이터베이스를 중지하기 위하여 심볼릭 링크를 한다.
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc0.d/K01oracle9i
[root@ora9 /]# ln -s /etc/rc.d/init.d/oracle9i /etc/rc.d/rc6.d/K01oracle9i
Oracle Database를 재시작 시켜본 후, LISTENER 데몬이 띄워져 잇는지 확인합니다.
[root@ora9 /]# /etc/rc.d/init.d/oracle9i restart
[root@ora9 /]# ps ax | grep LISTENER
여기까지 따라오시느라 수고 많으셨습니다. ^^

출처 : http://blog.naver.com/mh007kim/80004437666
Pooling 기법이란?

Pooling 기법이란 미리 데이터베이스 Connection을 여러 개 만들어서 특정 공간에 저장해 놓고,
여러 사용자가 필요할 때 마다 하나씩 꺼내서 사용하고 다시 집어 넣는 방식을 말합니다. 지금까지는 JDBC에서 Connection이 필요할 때마다 생성하고, 직접 종료 시켜야 했습니다. 하지만 Connection Pooling 기법에서는 Connection Pool이라는 커넥션 관리자가 연결과 해제를 직접 관리 합니다. 데이터베이스 작업을 수행할 JSP 파일들은 Connection Pool로부터 커넥션을 하나 할당 받아서 사용하고, 사용한 후에는 다시 Connection Pool에게 넘겨줍니다. Cnnection Pool에게 넘겨진 Connection은 다른 데이터베이스 연결이 있을 때 재사용됩니다.


 
Pooling 기법

n       Connection을 생성해서 보관

n       Connection에 대한 요청이 들어오면, 보관중인 Connection중 하나를 넘겨줌

n       사용이 끝난 Connection을 다시 보관



< 출처 : http://www.jabook.org/ >



< 출처 : http://www.jabook.org/ >

Connection Pooling 기법을 사용하는 이유는 다음과 같습니다.

     Connection Pooling의 장점
n       속도향상
n       자원공유
n       Connection객체 제어

Connection 클래스는 객체화 될 때, 다른 일반적인 클래스들과는 달리 수초의 시간이 걸립니다.
이 시간은 만약 데이터베이스가 원격지에 존재한다면, 네트워크의 상태에 따라 더 지연이 될 수도 있습니다. 만약 우리가 만들 JSP 페이지가 빈번하게 데이터베이스 Connection 을 생성한다면, 이러한 시간적인 오버헤드는 전체 JSP를 느리게 만들 것입니다. 이 경우, JSP가 시작될 때 일정수의 Connection을 미리 만들어 놓고, Connection Pool을 통해 재사용 한다면 상당한 속도 향상을 기대할 수 있을 것입니다.

또 다른 측면에서 살펴보면, 데이터베이스에 대한 Connection은 우리의 시스템이 가지고 있는 자원(CPU, MEMORY, 네트워크 대역폭 등)을 일정량 사용하고 있습니다. 시스템의 자원은 한정 되어 있기 때문에, 사용자 수가 많다고 해서, 무제한 데이터베이스 Connection을 만들 수는 없습니다. 만약 시스템이 가지고 있는 자원을 초과해서 Connection을 생성하고 사용한다면, 전체 시스템의 성능은 크게 떨어질 것입니다. 또한 갑자기 시스템이 정지하는 등 예측할 수 없는 상황을 불러 일으킬 수도 있습니다. 이런 경우를 막기 위해, Connection Pool에 시스템이 허용 가능한 수만큼의 데이터베이스 Connection을 만들어 놓고, 공유해서 사용함으로써 전체 시스템의 성능을 향상시키고 안정되게 만들어 줄 수 있습니다.

출처 : http://blog.naver.com/reomereome?Redirect=Log&logNo=40026698128

1. 일단 txt를 날짜 형식으로 변환하는 방법

DateTime convDate = DateTime.Now;   //기본값으로 현재 날짜를 넣어 둡니다.
string strDate = "2004-03-18";              //임의의 날짜값을 받습니다.
convDate = DateTime.Parse(strDate);   // 스트링 형식의 날짜를 Date 형식으로 바꾸어 놓은 것입니다.

이 형변환을 통해 나중에 날짜 비교를 할때  사용하는 거죠...

2. 두 날짜간의 순서 비교
이 비교는 단순비교로 두개의 날짜를 비교해서 값을 리턴해 주는 것으로,
기준값(t1) 보다 비교값(t2)가 더 크면  (즉 t1의 날짜가 t2의 날자가 더 나중이면, t1<t2) -1을 리턴,   기준값(t1) 보다 비교값(t2)가 더 작으면(즉 t1의 날짜가 t2의 날자가 더 이전이면, t1>t2) 1을 리턴,  기준값(t1) 보다 비교값(t2)가 같으면(즉 t1의 날짜가 t2의 날자가 같으면, t1=t2) 0을 리턴합니다.

MSDN의 내용을 발췌하면...

DateTime t1 = new DateTime(100);
DateTime t2 = new DateTime(20);
if (DateTime.Compare(t1, t2) >  0) Console.WriteLine("t1 > t2");
if (DateTime.Compare(t1, t2) == 0) Console.WriteLine("t1 == t2");
if (DateTime.Compare(t1, t2) <  0) Console.WriteLine("t1 < t2");

이렇게 되는 것이구요.
실제 날짜를 비교해서 넣으면,(<--저 같은 초보를 위해...)

DateTime t1 = new DateTime("2004-03-17");
DateTime t2 = new DateTime("2004-03-18");
if (DateTime.Compare(t1, t2) >  0) Console.WriteLine("t1 > t2");
if (DateTime.Compare(t1, t2) == 0) Console.WriteLine("t1 == t2");
if (DateTime.Compare(t1, t2) <  0) Console.WriteLine("t1 < t2");

이러면 답은...뭐가 될까요?...답은...  -1이 리턴되며  표시는 t1< t2 가 화면에 표시 되겠죠?...ㅎㅎㅎ

3. 특정일에서 특정일 더하거나 빼거나 해서 날짜 구하는 법
오늘을 기준으로 날짜를 30일 더하거나 빼는 방법은...

30일 더하는 방법 : DateTime.Today.AddDays(30).ToString("yyyyMMdd")
30일 빼는 방법 : DateTime.Today.AddDays(-30).ToString("yyyyMMdd")

4. 두 날짜 사이의 간격을 구하는 방법
DateDiff 인가 하는 것이 VB에도 있구, SQL에도 있는 것인데...C#에서는 이렇게 한답니다.(사실은 이것 땜시 공부를 한거죠...ㅎㅎㅎ...)   TimeSpan을 사용하는 것인데 두가지 방법이 있습니다. 뭐...같다고도 할 수 있죠...

DateTime t1 = DateTime.Now;    //날짜형 변수 t1을 선언하는데 기본값으로 현재 날짜를 설정합니다.
DateTime t2 = DateTime.Now;    //아래부분은 사실 두개의 택스트 박스의 값을 입력 받은 것입니다.
t1 = DateTime.Parse(txt_StartDay.Text); // 이 내용은 한줄로도 가능하며...이런 형식입니다. 괜히 길게썼죠?...
t2 = DateTime.Parse(txt_EndDay.Text);  // DateTime t1 =DatTime.Parse("2004-03-18");

//TimeSpan을 쓰는 두가지 방법. 방법(1)
TimeSpan t3 = t2.Subtract(t1);

//TimeSpan을 쓰는 두가지 방법. 방법(2)
TimeSpan t4 = t2 - t1;

//위의 날짜차이를 계산하여 int 형식으로 리턴해 주며 쓰기는 이렇게 씁니다. t5, t6의 값은 같습니다.
int t5 = t3.Days;
int t6 = t4.Days;

만약 t1의 날짜가 "2004-03-18" 이고 t2의 날짜가 "2004-03-01" 이라면 -17을 리턴해 주겠죠?

출처 : http://blog.naver.com/corea4004/120007284388

가끔 부득이하게 DB에서 여러 문자열을 붙여서 읽어와야하는 경우가 있다.
이런경우 원하는 문자열을 얻기 위해서 C#에서는 IndexOf메서드와 Substring메서드를 사용할 수 있다.

예를 들어 다음과 같이 자신의 아이디와 이메일을 붙여서 읽어온 경우에는,

'c_shop' + '&' + 'choiseungdo#email.com'

다음과 같이 처리 할 수 있다.

string ex = "c_shop&choiseungdo#email.com";
int index = ex.IndexOf('&') + 1;
string ex2 = ex.Substring( index, ex.Length - index );

위에서 '+1'을 한 이유는

             ↓ indexOf = 7
"c_shop&choiseungdo#email.com"
               ↑ 여기서 부터 읽어서 잘라야 하기 때문에
                int index = ex.IndexOf('&') + 1; 이 되는 것이다.

또한 ex.Substring( index, ex.Length - index );에서 
ex.Length - index를 한 이유는 index부터 시작해서 잘라 읽어오기 때문에 ex.Length만큼 읽어오면 배열의 범위를 벗어나는 오류가 발생한다. 따라서 index만큼 제외한 길이를 읽어와야 하는 것이다.

↓               ex.Length                 ↓
"c_shop&choiseungdo#email.com"
               ↑ --ex.Length - index--↑

폼의 버튼에 gif 애니메이션 그림을 넣으려고 합니다.  
버튼의 이미지 속성에다 파일경로를 적어주니까 그냥 멈춘 그림으로 보여서요.

--> 그럴 때 쓰는 것이 ImageAnimator타입이죠.

출처 : http://www.c-sharpcorner.com/Code/2002/Nov/ThreadPoolGifs.asp

매크로를 활용하시면 좋습니다.

1. "도구" / "매크로" / "매크로 탐색기" 를 선택.
2. 아무 모듈이나 선택하고( 예를 들어, Module1 ). 더블클릭
3. 다음과 같은 텍스트를 복사
       Sub WriteCurrentTime()
        DTE.ActiveDocument.Selection.Text = System.DateTime.Now.ToString()
    End Sub
4. 필요할 때 마다,  매크로 탐색기에서 해당 함수를 더블 클릭.


매크로에서 출력만 적절하게 조합해 주시면, 귀찮은 주석 문장들을 모두 자동화할 수 있습니다. ^^

출처 : http://www.dotnetxpert.com

저자: 워이밍 리(Wei-Meng Lee), 역 한동훈


처음 닷넷을 접하는 개발자들의 공통된 문제는 닷넷 클래스 라이브러리의 수가 너무 많다는 것이다. 근래에 필자는 파일 액세스와 관련된 프로젝트를 진행하게 되면서 파일 처리에 대한 올바른 클래스를 찾아보았다. 파일 관련 클래스의 대부분은 System.IO 네임 스페이스에 있으며, 각각의 클래스들은 서로 비슷한 점이 많으므로 일반적인 파일 처리를 수행하는데 사용하는 클래스들을 정리해 보기로 마음먹었다. 본 기사에서 소개할 예제가 좀 어렵게 느껴질 수도 있겠지만 여러분이 적절한 클래스를 선택하는데 도움이 될 것은 확실하다.


Stream 클래스

스트림은 바이트 순서를 추상화한 것이다. 파일, TCP/IP 소켓, 메모리로부터 오는 것들은 모두 바이트 순서라 할 수 있다. 닷넷에서는 이러한 스트림을 Stream 클래스로 표현한다. Stream 클래스는 바이트 순서의 일반적인 뷰를 제공한다. 또한 Stream 클래스는 다른 모든 스트림의 추상 클래스이므로 Stream 클래스의 인스턴스를 직접 생성할 수 없다. 대신에 Stream 클래스는 다음과 같은 클래스로 구현된다.

BufferedStream - 성능 향상을 위해 다른 스트림에 대한 버퍼링 레이어를 제공한다
FileStream - 파일을 읽기/쓰기 기능을 제공한다
MemoryStream - 보조 저장 수단으로서 메모리를 사용하는 스트림을 제공한다
NetworkStream - 네트워크 데이터를 액세스할 수 있는 스트림을 제공한다
CryptoStream - 데이터를 암호화 전송할 수 있는 스트림을 제공한다

스트림 클래스들은 기본적으로 다음과 같은 작업을 수행한다.
- 읽기(Reading), 쓰기(Writing), 찾기(Seeking)

본 기사에서는 파일 입출력에서 빈번하게 사용되는 클래스들을 예제를 통해 살펴볼 생각이다. 비주얼 스튜디오 닷넷과 함께 제공되는 MSDN에는 각 클래스에 대한 문서화가 잘 되어 있기 때문에 여기에서는 각 클래스를 일일이 설명하는 대신 FileStream과 MemoryStream에 대해서만 살펴보고 파일 생성, 읽기, 쓰기에는 File 클래스를 사용할 것이다. 소제목을 수행할 작업에 따라 나누고, 그에 대한 예제를 설명하였다.

여기에 등장한 모든 예제는 다음 상수와 변수들을 사용한다.

Dim fs, s1, s2 As FileStream
Dim sr As StreamReader
Dim sw As StreamWriter
Dim br As BinaryReader
Dim bw As BinaryWriter
Dim ms As MemoryStream

Const FILE_NAME = "c:\textFile.txt"
Const BAK_FILE_NAME = "c:\textFile_bak.txt"
Const FILE_NAME_IMAGE = "c:\iMac.jpg"
Const FILE_NAME_BIN = "c:\bin.jpg"
Dim bytes(10) As Byte


지금까지 언급한 클래스들은 모두 System.IO 네임 스페이스에 있으므로 이 네임 스페이스를 임포트한다.

Imports System.IO


FileStream과 MemoryStream 외에 바이너리 데이터의 읽기/쓰기를 위해 BinaryReader와 BinaryWriter 클래스를 사용하며, 텍스트 데이터의 읽기/쓰기에는 StreamReader와 StreamWriter 클래스를 사용할 것이다.


참고 도서 : VB.NET Core Classes in a Nutshell
Budi Kurniawan, Ted Neward

상세설명보기
목차보기
샘플챕터보기


파일 관리

파일 생성, 삭제, 복사, 이름 변경, 지정된 파일이 있는지를 확인하기 위해 File 클래스를 사용한다. 다음 예제는 파일이 있는지 확인한 후, 파일을 복사하고 원본을 삭제한다.

'---Copy and Delete the file
If File.Exists(FILE_NAME) Then
File.Copy(FILE_NAME, BAK_FILE_NAME, True)
File.Delete(FILE_NAME)
End If


파일 생성

파일 읽기 외에 파일 생성에도 File 클래스를 사용한다. 다음 예제는 파일을 생성하고 FileStream 객체를 반환한다.

그 다음 코드는 새로운 텍스트 파일을 생성하고 StreamWriter 객체를 반환한다. 마지막으로 파일의 읽기/쓰기를 위해 File 클래스의 Open() 메소드를 사용한다.

fs = File.Create(FILE_NAME_BIN)
fs.Close()

sw = File.CreateText(FILE_NAME)
sw.Close()

fs = File.Open(FILE_NAME, FileMode.Open, FileAccess.Read, FileShare.Read)
fs.Close()


FileStream 클래스를 사용하여 바이너리 데이터 쓰기

바이너리 데이터를 파일에 저장하기 위해 FileStream 클래스를 사용한다. 다음 예제는 FileStream 클래스를 사용하여 새로운 파일을 생성하고 데이터를 바이너리로 저장한다. 모두 11바이트를 파일에 저장한 후 파일을 닫는다.

'---create a file and write some bytes to it
fs = New FileStream(FILE_NAME, FileMode.CreateNew, FileAccess.Write)
bytes(0) = 72 'H'
bytes(1) = 101 'e'
bytes(2) = 108 'l'
bytes(3) = 108 'l'
bytes(4) = 111 'o'
bytes(5) = 13 'CR'
bytes(6) = 87 'W'
bytes(7) = 111 'o'
bytes(8) = 114 'r'
bytes(9) = 108 'l'
bytes(10) = 100 'd'

fs.Write(bytes, 0, bytes.Length)
fs.Close()


StreamWriter 클래스를 사용하여 텍스트 쓰기

텍스트를 파일에 저장할 때는 다른 클래스를 사용하는 것 보다 StreamWriter 클래스를 사용하는 것이 더 쉽다. 다음 예제는 파일에 텍스트 문자열을 저장하기 위해 StreamWriter 클래스를 사용한다.

'---Using a streamWriter to write to a file
sw = New StreamWriter(FILE_NAME, True, System.Text.ENCODING.ASCII)
sw.WriteLine("Welcome to VB.NET")
sw.Close()


FileStream 클래스를 사용하여 바이너리 데이터 읽기

파일에서 바이너리 데이터를 읽어오려면 FileStream 클래스를 사용해야 한다. 다음 예제는 파일을 열고 바이너리 데이터를 읽어온다. 읽어온 바이트를 ASCII 문자로 변환한 다음에 화면에 출력한다.

'---open a file and read the byte(s) out
fs = New FileStream(FILE_NAME, FileMode.Open, FileAccess.Read)
fs.Read(bytes, 0, bytes.Length)
Dim i As Short
For i = 0 To bytes.Length - 1
 Console.Write(Chr(bytes(i)))
Next


찾기(Seeking)

스트림 객체는 찾기를 지원한다. 다음 예제는 FilStream 객체를 사용하여 현재 위치에서 11번째 바이트로 이동한 후에 6 바이트를 읽어온다.

'---seeking
fs.Seek(11, SeekOrigin.Current)
fs.Read(bytes, 0, 6)
For i = 0 To 5
 Console.Write(Chr(bytes(i)))
Next
fs.Close()


※ 역자주: Read 함수들은 데이터를 읽어온 다음에 현재 위치를 다음 위치로 이동시키지만 Seek 함수들은 데이터를 읽어오기만 하며 위치를 이동시키지 않는다. 여기에 소개된 예제처럼 파일 내에서 위치를 이동하기 위해 Seek를 사용하기도 한다.


StreamReader 클래스를 사용하여 텍스트 읽기

텍스트 파일을 읽어오기 위해 StreamReader 클래스를 사용한다. 다음 예제는 StreamReader 객체를 사용하여 읽어올 파일을 연다. 파일을 줄 단위로 읽어온 다음에 각 줄을 화면에 출력한다.


'---open a file and read line by line using a streamreader
sr = New StreamReader(FILE_NAME)
Dim line As String = sr.ReadLine()

While Not line Is Nothing
Console.Write(line)
line = sr.ReadLine()
End While
sr.Close()


BinaryReader와 BinaryWriter 클래스를 사용하여 바이너리 데이터 읽고 쓰기

바이너리 데이터의 읽기/쓰기에는 FileStream 클래스 뿐만 아니라 BinaryReader와 BinaryWriter 클래스도 사용할 수 있다. 다음 예제는 하나의 파일을 읽어와서 다른 파일에 그 내용을 저장하는 것으로 결국에는 파일을 복사하는 것과 동일하다. 예제에서는 FileStream 클래스를 사용하여 두 개의 파일을 연다. 하나는 파일을 읽어오기 위한 것이며, 다른 하나는 파일을 저장하기 위한 것이다. FileStream에서 바이너리 데이터를 읽어오기 위해 BinaryReader 클래스를, 바이너리 데이터를 파일에 저장하기 위해 BinaryWriter 클래스를 사용한다.

'---read from and write to a binary file
s1 = New FileStream(FILE_NAME_IMAGE, FileMode.Open, FileAccess.Read)
s2 = New FileStream("c:\iMac_copy.jpg", FileMode.CreateNew, FileAccess.Write)

br = New BinaryReader(s1)
bw = New BinaryWriter(s2)

Dim byteRead As Byte
Dim j As Integer
For j = 0 To br.BaseStream.Length() - 1
byteRead = br.ReadByte
bw.Write(byteRead)
Next
br.Close()
bw.Close()


MemoryStream 클래스를 사용하여 바이너리 데이터 쓰기

특별한 용도를 위해 파일에서 읽어온 바이너리 데이터를 메모리에 저장하는 경우가 있다. 이러한 경우의 가장 좋은 예는 윈도우 폼에서 사용하는 PictureBox 컨트롤이다. 다음 예는 BinaryReader 클래스를 사용하여 파일을 바이너리 데이터로 읽어와서 MemoryStream 객체에 저장한다. 그 다음에 PictureBox 컨트롤은 MemoryStream에 비트맵 이미지로 저장된 데이터를 사용한다.

'--read from a binary stream and write into a memory stream
s1 = New FileStream(FILE_NAME_IMAGE, FileMode.Open, FileAccess.Read)
ms = New MemoryStream(s1.Length)
br = New BinaryReader(s1)
Dim bytesRead As Byte() = br.ReadBytes(s1.Length)
ms.Write(bytesRead, 0, s1.Length)
PictureBox1.Image = New Bitmap(ms)


나머지 유용한 함수들

암호화 API를 사용하는 경우와 같이 문자열을 바이트 배열로 변환하거나 그 반대로 변환할 필요가 있다. 이러한 변환을 쉽게 할 수 있는 세가지 함수를 살펴보자.

stringcharToByteArray(): 문자열을 바이트 배열로 변환한다
stringToByteArray(): 숫자로 구성된 문자열을 바이트 배열로 변환한다
byteArrayToString(): 바이트 배열을 문자열로 변환한다


Public Function stringcharToByteArray(ByVal str As String) As Byte()
'e.g. "abcdefg" to {a,b,c,d,e,f,g}
Dim s As Char()
s = str.ToCharArray
Dim b(s.Length - 1) As Byte
Dim i As Integer
For i = 0 To s.Length - 1
 b(i) = Convert.ToByte(s(i))
Next
Return b
End Function


Public Function stringToByteArray(ByVal str As String) As Byte()
' e.g. "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16" to
'{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}
Dim s As String()
s = str.Split(" ")
Dim b(s.Length - 1) As Byte
Dim i As Integer
For i = 0 To s.Length - 1
 b(i) = Convert.ToByte(s(i))
Next
Return b
End Function


Public Function byteArrayToString(ByVal b() As Byte) As String
Dim i As Integer
Dim s As New System.Text.StringBuilder()
For i = 0 To b.Length - 1
 Console.WriteLine(b(i))
 If i <> b.Length - 1 Then
  s.Append(b(i) & " ")
 Else
  s.Append(b(i))
 End If
Next
Return s.ToString
End Function


※ 역자주: 위에 소개한 유틸리티 함수들은 닷넷 프레임워크의 System.Text 네임스페이스의 ENCODING.GetBytes()와 ENCODING.GetString()으로 이미 구현되어 있다

아이콘에 마우스를 올려 놓으면 단축키가 나오면 매우 편리하겠는데...
옵션에는 그런 것이 보이지 않는다. 그런데, 그 옵션은 다른데 있었다.

[도구모음 오른쪽클릭] -> 사용자 지정 -> 옵션 -> 스크린 팁에 바로가기 키 표시

이렇게 하면 단축키가 팁에 같이 올라온다....

C#은 클래스 내부의 멤버를 노출하거나 숨길때 사용하도록 여러 접근 한정자를 제공합니다. 일반적으로 클래스는 자신의 멤버 데이터는 외부에 대해 숨기고, 필요한 메쏘드만 노출합니다. 데이터를 숨기는 이유는 클래스 외부에서 누군가가 그 데이터의 값을 변경할 수 있게 되면 나중에 프로그램에 문제가 생겼을 때 문제가 어디서 발생했는지를 발견하기가 매우 힘들어지기 때문입니다. class는 접근 제한자를 명시해주지 않으면 기본적으로 private으로 접근 제한자를 적용합니다. (그 외의 한정자 대해서는 아래 다 링크가 되어있습니다.)

한정자 용도
액세스 한정자 형식 및 형식 멤버의 선언된 액세스 가능성을 지정합니다.
abstract 클래스가 다른 클래스의 기본 클래스로만 사용됨을 나타냅니다.
const 필드 또는 지역 변수의 값을 수정할 수 없도록 지정합니다.
event 이벤트를 선언합니다.
extern 메서드가 외부에서 구현됨을 나타냅니다.
override 기본 클래스로부터 상속된 가상 멤버의 새 구현을 제공합니다.
readonly 선언의 일부로서 또는 동일한 클래스의 생성자에서만 값을 할당받을 수 있는 필드를 선언합니다.
sealed 클래스가 상속될 수 없도록 지정합니다.
static 특정 개체가 아니라 형식 자체에만 속하는 멤버를 선언합니다.
unsafe 안전하지 않은 컨텍스트를 선언합니다.
virtual 파생 클래스의 재지정 멤버에 의해 구현이 변경될 수 있는 메서드 또는 접근자를 선언합니다.
volatile 필드가 운영 체제, 하드웨어 또는 동시에 실행되는 스레드 등에 의해 프로그램에서 수정될 수 있음을 나타냅니다.
new 기본 클래스 멤버에서 상속된 멤버를 숨기는 데 사용됩니다.

출처 : MSDN

SQL문은 프로시져로 되어 있구요 아주 기초적인것이라.. 크리스탈리포트로 인쇄하는 기본적인것을 알려고할때 좋은 자료인것 같습니다...

프로시저 내용은
-- 크리스탈 레포트 출력 예제를 위한 스토어드 프로시져
CREATE PROCEDURE REPORT_TEST
@CustomerID VARCHAR(20) = '' -- 검색어
AS
BEGIN
SELECT OrderID
, CustomerID
, EmployeeID
, OrderDate
FROM Orders
WHERE CustomerID Like '%' + LTRIM(@CustomerID) + '%'
ORDER BY OrderID ASC
END

출처: http://cafe.daum.net/aspdotnet

7.0 앞부분에 해당하는 메뉴얼 이지만....8.0 에서도 적용할 수 있는 부분이 상당하다.

-크리스탈리포트 닷넷을 이용한 웹리포팅 관련 엑셀 출력 및 PDF출력 리포팅 방식을 설명드립니다.

using System;
using System.Data;
using System.Data.SqlClient;
using CrystalDecisions.Shared;
using CrystalDecisions.ReportSource;
using CrystalDecisions.CrystalReports.Engine;

namespace JDictionary.Dictionary
{

   /// <summary>
   /// ExportPDFSearch에 대한 요약 설명입니다.
   /// </summary>
   public class ExportPDFSearch : System.Web.UI.Page
   {
       protected CrystalDecisions.Web.CrystalReportViewer CrystalReportViewer1;

       private void Page_Load(object sender, System.EventArgs e)
       {
           if(!Page.IsPostBack)
           {
               string SearchOption=Request.QueryString["soption"].ToString();
               string SearchWord=Request.QueryString["sword"].ToString();
               string gubun=Request.QueryString["gubun"].ToString();

               if(gubun=="1")
               {
                   ExportPDF(SearchOption,SearchWord);
               }
               else
               {
                   ExportExcel(SearchOption,SearchWord);
               }
           }
       }

       private string GetDBString()
       {
           return System.Configuration.ConfigurationSettings.AppSettings["DSN"].ToString();
       }

       private void ExportPDF(string SearchOption,string SearchWord)
       {
           ReportDocument crReportDocument = new ReportDocument();
           ExportOptions crExportOptions = new ExportOptions();
           DiskFileDestinationOptions crDiskFileDestinationOptions = new DiskFileDestinationOptions();

           SqlConnection conn = new SqlConnection(GetDBString());
           SqlCommand comm = new SqlCommand("up_searchword_export",conn);
           comm.CommandType = CommandType.StoredProcedure;

           SqlParameter param = new SqlParameter();
           param = comm.Parameters.Add("@searchoption", SqlDbType.VarChar,20);
           param.Direction = ParameterDirection.Input;
           param.Value = SearchOption.ToString();
           param = comm.Parameters.Add("@searchword", SqlDbType.VarChar,100);
           param.Direction = ParameterDirection.Input;
           param.Value = SearchWord.ToString();

           SqlDataAdapter adapter = new SqlDataAdapter(comm);
           dsDictionary ds = new dsDictionary();
           adapter.Fill(ds, "up_searchword_export");
           crReportDocument = new rptSearchWordPDF();
           crReportDocument.SetDataSource(ds);

           CrystalReportViewer1.ReportSource = crReportDocument;
           CrystalReportViewer1.SeparatePages = false;
           CrystalReportViewer1.DisplayGroupTree = false;
           CrystalReportViewer1.DisplayToolbar = false;

           string ExportRoot = System.Configuration.ConfigurationSettings.AppSettings["ExportRoot"];
           string Fname = ExportRoot+Session.SessionID.ToString()+".pdf";
           crDiskFileDestinationOptions.DiskFileName = Fname;
           crExportOptions = crReportDocument.ExportOptions;

           crExportOptions.DestinationOptions = crDiskFileDestinationOptions;
           crExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;
           crExportOptions.ExportFormatType = ExportFormatType.PortableDocFormat;
           crReportDocument.Export();

           //Response.ClearContent();
           //Response.ClearHeaders();
           Response.ContentType = "application/pdf";
           Response.WriteFile(Fname);
           Response.Flush();
           Response.Close();

           System.IO.File.Delete(Fname);
       }

       private void ExportExcel(string SearchOption,string SearchWord)
       {
           ReportDocument crReportDocument = new ReportDocument();
           ExportOptions crExportOptions = new ExportOptions();
           DiskFileDestinationOptions crDiskFileDestinationOptions = new DiskFileDestinationOptions();

           SqlConnection conn = new SqlConnection(GetDBString());
           SqlCommand comm = new SqlCommand("up_searchword_export",conn);
           comm.CommandType = CommandType.StoredProcedure;

           SqlParameter param = new SqlParameter();        
           param = comm.Parameters.Add("@searchoption", SqlDbType.VarChar,20);
           param.Direction = ParameterDirection.Input;
           param.Value = SearchOption.ToString();
           param = comm.Parameters.Add("@searchword", SqlDbType.VarChar,100);
           param.Direction = ParameterDirection.Input;
           param.Value = SearchWord.ToString();

           SqlDataAdapter adapter = new SqlDataAdapter(comm);
           dsDictionary ds = new dsDictionary();
           adapter.Fill(ds, "up_searchword_export");

           crReportDocument = new rptSearchWordExcel();
           crReportDocument.SetDataSource(ds);

           CrystalReportViewer1.ReportSource = crReportDocument;
           CrystalReportViewer1.SeparatePages = false;
           CrystalReportViewer1.DisplayGroupTree = false;
           CrystalReportViewer1.DisplayToolbar = false;

           string ExportRoot = System.Configuration.ConfigurationSettings.AppSettings["ExportRoot"];
           string Fname = ExportRoot+Session.SessionID.ToString()+".xls";
           crDiskFileDestinationOptions.DiskFileName = Fname;
           crExportOptions = crReportDocument.ExportOptions;
           crExportOptions.DestinationOptions = crDiskFileDestinationOptions;
           crExportOptions.ExportDestinationType = ExportDestinationType.DiskFile;
           crExportOptions.ExportFormatType = ExportFormatType.Excel;
           crReportDocument.Export();

           Response.ClearContent();
           Response.ClearHeaders();
           Response.ContentType = "application/vnd.ms-excel";
           Response.WriteFile(Fname);
           Response.Flush();
           Response.Close();

           System.IO.File.Delete(Fname);
       }

       #region Web Form 디자이너에서 생성한 코드
       override protected void OnInit(EventArgs e)
       {
           InitializeComponent();
           base.OnInit(e);
       }
 
       private void InitializeComponent()
       {    
           this.Load += new System.EventHandler(this.Page_Load);
       }
       #endregion
   }
}

출처 : http://cafe.naver.com/82csharp/17

크리스탈 레포트 프로그램에서
메뉴 중 파일 > 프린터 설정 > 방향에서 '가로'를 선택하면 디자인 모습이 가로로 변경된다.

<.NET Source측 제어>
using CrystalDecisions.Shared;    //NameSpace
report.PrintOptions.PaperOrientation = PaperOrientation.Landscape;

* 이래도 안돼면....
프린터 출력하기 직전에 나오는 옵션창의 '기본 설정'에서 용지의 출력방향을 '가로'로 해 주면 된다....^^;;

Crystal Report v10사용시 자동으로 가로출력하기
<출처: 데브피아>

Crystal Report V10을 ASP.Net에서 사용할때 Viewer의 출력버튼을 클릭하였을때 출력 다이얼로그 창이 뜨고 인쇄옵션에서 "가로"항목을 체크해야지만 가로로 출력이 되는데. 인쇄옵션에서 인쇄방향에 대한 항목을 체크하지 않고 자동으로 rpt파일이 출력형태에 따라 가로이면 가로로 세로형태이면 세로에 체크되게.. 즉 그냥 출력 다이얼로그창에서 인쇄버튼만 누르면 해당하는 방향으로 출력하게 해주는 방법입니다.
소스상에서 PaperOrientation.Landscape를 설정하지 않아도 됩니다.

<방법>

우선 크리스탈 레포트 설치시  생성되는 폴더 중에 아래와 같은 경로에
http://pds5.devpia.com/aspnet_lec/1000/564/http://pds5.devpia.com/aspnet_lec/1000/564/crystalprinthost.html이라는 파일의 내용을 일부 수정해주면 됩니다. (수정내용은 첨부된 파일을 살펴보시기 바랍니다.)

경로: C:\Program Files\Common Files\Crystal Decisions\2.5\crystalreportviewers10\html

내용은 다음과 같습니다.

Viewer에서 출력버튼을 클릭하면 http://pds5.devpia.com/aspnet_lec/1000/564/http://pds5.devpia.com/aspnet_lec/1000/564/crystalprinthost.html파일이 ShowModal로 뜨게됩니다.
이때 Viewer페이지에서 rpt파일의 출력정보를 넘겨주는데. http://pds5.devpia.com/aspnet_lec/1000/564/http://pds5.devpia.com/aspnet_lec/1000/564/crystalprinthost.html파일 소스를 확인하니 window.dialogArguments.pageorientation값을 받아서 출력 다이얼로그 창의 가로 출력여부를 설정하는것으로 보입니다.

근데 문제는 Viewer페이지에서 가로출력에 대한 값을 window.dialogArguments.pageorientation변수가 아닌 window.dialogArguments.paperorientation이라는 변수로 넘겨주고 있습니다.값은 rpt 파일을 작성할때 설정(가로출력)을 가져오는듯한데 'Landscape'인것을 확인하였습니다. 하여 첨부한 파일의 소스를 확인하시면 아시겠지만 약간의 소스를 추가하였습니다.  또한 window.dialogArguments.usedefprinter값을 받는 if문은 막아야지 출력 다이얼로그 창에서 유저가 가로출력을 설정하지 않아도 가로로 출력이 가능하게 됩니다.

- IIS Version 5 사용시
기본적으로 .NET Framework은 ASP.NET 계정으로 작동을 합니다.
ASP.NET계정에 레지스터리 관련 권한이 없습니다.
.Net Framework 1.0과 1.1의 Machine.config 파일에서
( 파일위치 :
winnt\Microsoft.NET\Framework\v1.0.3705
winnt\Microsoft.NET\Framework\v1.1.4322 )


userName="SYSTEM"
password="AutoGenerate" logLevel="Errors" clientConnectedCheck="0:00:05" comAuthenticationLevel="Connect" comImpersonationLevel="Impersonate" responseDeadlockInterval="00:03:00" maxWorkerThreads="20" maxIoThreads="20"/>

userName="SYSTEM" 으로 수정해 주시면 됩니다.
기본값은 machine입니다.


- IIS Version 6 사용시
IIS관리자를 실행.
DEXTUploadPool이란 응용 프로그램 풀을 생성 한후 이 풀의 등록정보->ID 미리 정의된 보안계정을 로컬 시스템으로 지정.
웹사이트 전체의 응용 프로그램 풀을 DEXTUploadPool로 지정.
또는 DEXTUpload.NET을 사용하는 디렉토리를 가상디렉토리로 지정 한후 여기서 DEXTUploadPool로 지정.

DEXTUpload.NET.dll 컴포넌트는 COM+상에서 동작하므로, 구성요소 서비스에 등록되어야 합니다. Regsvcs.exe를 이용하여 등록하시면 됩니다.

본 문서의 정보는 다음의 제품에 적용됩니다.
DEXTUpload.NET 3.0.3
DEXTUpload.NET Professional 3.5.0
· crdb_odbc.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· crdb_dao.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

· crdb_ado.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· Implode.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· sscsdk80.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· u25samp1.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· u25dts.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· u252000.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· u2lfinra.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

· u2lexch.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

· u2ldts.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· u2lcom.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· u2l2000.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· ufmanager.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· crtowords_en.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

· MSVCRT.DLL : {WinSysDir}

­· craxdrt.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일,Server 등록

· crviewer.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일,Server 등록

· cxlibw-1-6.dll : {WinSysDir}

­· etc-1-0-12-1.dll : {WinSysDir}

­· Emfgen.dll : {CommonFiles}\Crystal Decisions\2.5\bin, 공유 화일

­· msvcp60.dll : {WinSysDir}, 공유 화일

­· crqe.dll : {WinSysDir}, Server 등록

레지스트리: HKEY_LOCAL_MACHINE\SOFTWARE\Crystal Decisions\10.0\Crystal Reports,CommonFiles,문자열 값,c:\\program files\\common files\\crystal decisions\\2.5\\bin

대부분 다 정상적으로 등록이 될 것이다. 위의 dll은 크리스탈 레포트 10을 설치했다면

C:\Program Files\Common Files\Crystal Decisions\2.5\bin 폴더에 다 존재한다.

msvcp60.dll 같은 경우는 2000에서 없는 컴이 있더군요 이게 없음 crqe.dll 이 등록이 안됩니다.
cxlibw-1-6.dll, etc-1-0-12-1.dll 이녀석들이 없어도 안되구요. 이녀석들은 해당 개발 PC 윈도우 시스템 디렉토리에 있습니다
msvcp60.dll 도 역시 시스템 디렉토리에 있구요. 그리고 당연한거지만  cxlibw-1-6.dll, etc-1-0-12-1.dll, msvcp60.dll crqe.dll 은 같은 폴더에 있어야 crqe.dll이 등록이 되더군요. 이녀석이 등록 안되면 TLV 에러가 뜹니다.

비쥬얼 툴에 depends 툴을 이용해서 보면 etc-1-0-12-1.dll 이녀석은 의존성이 없던데요. 여기 질답글 보니까 이녀석도 있길래 혹시나 하고 넣었습니다. 레지스트리에는 위에 쓴 키값하고 밸류값을 넣어 주심 됩니다. 인스톨 팩토리에서 다 가능합니다. 마지막으로 저의 경우는 크리스탈 뷰어하고 TTX만 이용했습니다.크리스탈 리포트의 다른 객체 머 챠트라던가 그런 걸 쓰셨다면 더 많은 DLL이 필요 할겁니다. 2000 하고 2003에서는 잘 설치되고 잘 실행 됐습니다. xp하고 98은 아직 모르겠습니다만...

출 처 : 데브피아 http://www.devpia.com/forum/BoardView.aspx? no=182&ref=182&page=1&forumname=crystal_lec&stype=

+ Recent posts