글
Pro*C에서 변수의 사용
1. 데이터의 Type
C변수 타입 | 설명 |
char | single charactor |
char[n] | n-charactor array(string) |
Int | integer |
Short | small integer |
Long | large integer |
Float | floating-point number(usually single precision) |
Double | floating-point number(always double precision) |
VARCHAR[n] | variable-length string |
<table 3-1>호스트 변수를 위한 C데이타 타입
- C와 Oracle 데이타 타입 호환성
Internal Type(Oracle) | C Type | 설명 |
VARCHAR2(Y)(Y:1~2000) | char | single charactor |
CHAR(X)(X:1~255) | char[n]VARCHAR[n]intshortfloat | n-byte charactor arrayn-byte variable-length charactor arrayintegersmall integer |
NUMBERNUMBER(P,S) | intshortlongfloatdoublecharchar[n]VARCHAR[n] | integersmall integerlarge integerfloating-point numberdouble-precision floating-point numbersingle charactern-byte character arrayn-byte variable-length character array |
DATE | char[n]VARCHAR[n] | n-byte character arrayn-byte variable-length character array |
LONG | char[n]VARCHAR[n] | n-byte character arrayn-byte variable-length character array |
RAW(X) | unsigned char[n]VARCHAR[n] | n-byte character arrayn-byte variable-length character array |
LONG LAW | unsigned char[n]VARCHAR[n] | n-byte character arrayn-byte variable-length character array |
ROWID | unsigned char[n]VARCHAR[n] | n-byte character arrayn-byte variable-length character array |
MLSLABEL | unsigned char[n]VARCHAR[n] | n-byte character arrayn-byte variable-length character array |
Notes: |
<table 3-2> C와 Oracle 데이타 타입 호환성
- 2. Internal Data Type - 오라클 데이타 타입
문자 데이타 타입- char와 varchar2 datatype은 alphanumeric data로 저장.- database character set은 database를 생성할때 만들어지며 변경할 수 없다.
ⓛ char datatype- fixed-length character strings.- table을 생성할때 칼럼길이가 정의되며 1~255 bytes.(default 1)- table의 row를 insert나 update할때 char 칼럼은 고정된 length를 가짐.- 정해진 값보다 짧은 값이 입력되면 정해진 length만큼 이후는 blank가 채워짐.- trailing blank를 가진 정해진 값보다 긴 값이 입력되면 고정된 길이 내에서 trailing blank가 잘림.정해진 길이보다 긴 값이 입력되면 오라클은 에러를 return.
② Varchar2 datatype- variable-length character strings.- maximum 칼럼 length는 1~2000 bytes.- 입력된 길이 만큼만 저장됨.
③ Varchar datatype- varchar2 datatype 과 현재는 동일함.- 향후 오라클에서는 다른 용도로 사용계획. (varchar2를 사용하는 것이 향후에 유리)
3. 어떻게 데이타 타입을 정할 것인가?
Semantics 비교ANSI처럼 trailing blank 가 중요한 역할을 하지 않을때는 char사용.trailing blank 가 중요한 역할을 담당할때는 varchar2 사용.효과적인 데이터 저장을 위해서는 varchar2 가 유리.char datatype은 blank-pad를 하고 trailing blank를 fix 된 칼럼 길이 만큼 blank를 채워 저장.varchar2는 blank를 저장하지 않음.
Number 데이타 타입blank-pad : 'a'='a ', non-pad 'a '>'a'Future Compatibility
char와 varchar2 datatype은 지원이 되지만 varchar datatype는 향후 어떤 용도로 사용될지 모르기 때문에 사용하지 않는것이 좋다.fixed floating-point number로 저장.number (precision, scale)
Date 데이타타입precision-scale= 왼쪽정수의 수,scale은 오른쪽 소수이하의 수. (단,scale이 +일 경우) 38digits 까지 저장가능.
scale은 -84~127사이① Internal numeric formatvariable-length format.38digits 까지 저장가능. 지수가 1bytes 일때 가수는 20bytes까지 가능. (38digit/2)+1=20bytes4.12×10E2 일때 지수 1 bytes 차지 4,1,2 2bytes 차지. (3digits /2)=1.5 1+1=2bytes지수의 범위는 -130~125 사이
point-in-time value 으로 저장.Jan 1,4712 BC ~ Dec 31,4712 AD (AD가 default)기본형태는 DD-MON-YY기본 형태에서 벗어나는 날짜를 사용할때는 TO_DATE function을 사용.TO_DATE ('November 13,1992', 'MONTH DD,YYYY')ⓛ Julian date01-01-4712 BC부터 원하는 날까지의 날수 계산시 사용.format mask “J" 사용.TO_DATE 와 TO_CHAR fuction을 사용하여 date datatype과 상호 convert가능.select to_char (hiredate, 'J') from emp;(date type인 hiredate를 julian date로 convert)insert into emp (hiredate) values (to_date(2448921, 'J'));(julian date인 2448921을 date datatype으로 변환하여 hiredate 칼럼에 insert.)
Long 데이타타입variable-length character data2 gigabytes 까지의 data 저장.long data는 text data 이고 다른 시스템으로 옮길때 convert되어짐.주로 comment 등에 사용되어지는 datatype.사용자가 특별히 지정하지 않으면 80 bytes 만 출력.하나의 테이블에는 오직 하나의 long datatype 만 존재.not (null)을 제외한 다른 제약조건은 지정할 수 없음.조건절에서 사용되어 다른 것과 비교될수 없으며 인덱스를 만들수 없음.select 문 내에서 where의 조건, group by, order by등의 각종 함수를 사용할 수 없음.계산식에서 사용될 수 없음.
RAW and Long RAWRAW와 long raw datatype은 다른 시스템으로 상호 convert 되지 않는 data 에 사용.long raw 는 graphics,sound,documents,arrays of binary data를 저장하는데 사용.long raw는 2Gbytes 까지 저장이 가능하고, raw는 255bytes까지 저장.long raw는 인덱스가 불가능하고 raw 는 인덱스가 가능.raw나 long raw와 char 상호 자동 convert 되며 binary data는 hexadecimal form 으로 표현.* long raw의 경우는 2Gbytes나 되기 때문에 인덱스를 한다면 많은 시간과시스템 부하를 초래.
ROWID and ROWID datatype실제 row가 존재하는 테이블에는 rowid가 없으며 인덱스에만 rowid가 존재.non-clustered table 에 존재하는 각 row는 physical 한 address에 대한 unique 한 rowid가 존재.clustered table의 경우에는 같은 data block에 존재하는 다른 table의 row는 같은 rowid 를 가질수 있음.row에 할당된 rowid는 import나 export utility를 사용하여 import나 export 되지 않는 한 변경되지않음.table 로부터 row를 삭제할 때 그 row에 할당된 rowid는 다음에 insert되는 row에 할당됨.rowid는 database 에 저장되지도 않고, database data도 아님.
MLSLABEL datatypetrusted oracle에서 제공.이 datatype 은 binary format의 operating system label을 저장할때 사용.data dictionary에 있는 binary label에 대한 map을variable-length tag 형태로 저장.(row당 2~5bytes)binary label 대신 representative tag로 저장되는 것은 binary operating system label이 매우 크기 때문. (space 사용에 효과적.)
4. DATA conversion
여러 function 을 이용하여 오라클은 자동으로 datatype을 convert한다.ⓛRULE 1: Assignment
- assignment에 의하여 오라클은 자동으로 다음을 convert 한다.varchar2 or char to numbernumber to varchar2varchar2 or char to date· date to varchar2· varchar2 or char to rowid· rowid to varchar2· varchar2 or char to label· label to varchar2· varchar2 or char to hex ② RULE 2 : Expression evaluation- expression evaluation에 의하여 오라클은 자동으로 다음을 convert한다.· varchar2 or char to number· varchar2 or char to date variable :=expression 의 경우 오라클은 먼저 rule2를 사용하여expression을 계산. 성공적으로 계산이 되면 하나의 value값이 나오고datatype을 가짐. 이 다음에 rule1을 사용하여 이 value 값을assignment's target에 할당하려고 함.* char to number conversion은 character string이 유효숫자를 가질 때만가능. char to date 역시 character string이 date 기본 format인DD-MON-YY를 가질 때 가능.
- 5. 데이타 타입의 동격화(Datatype Equivalencing)
- typedef struct { unsigned short len; unsigned char arr[1]; } VARCHAR;/* VARCHAR형으로 선언된 호스트 변수의 실제모습 */VARCHAR user_name[20];struct { unsigned short len; /* 호스트 변수의 길이 저장 */ unsigned char arr[1]; /* 호스트 변수 데이타 저장 */} user_name;
- strcpy((char *) user_name.arr, "EDU");user_name.len = strlen(user_name.arr);
- 데이타 타입의 동격화(Datatype Equivalencing)의 사용
- EXEC SQL VAR 호스트 변수명 IS 외부데이타타입[(길이:길이, 소숫점이하 길이)]];EXEC SQL BEGIN DECLARE SECTION; char emp_name[11]; EXEC SQL VAR emp_name IS STRING(11); char emp_job[11]; EXEC SQL VAR emp_job IS STRING(11); char emp_ename[100][11]; EXEC SQL VAR emp_ename IS STRING(11); /* ARRAY 변수 정의 */EXEC SQL END DECLARE SECTION;
- EXEC SQL TYPE 사용자정의타입 IS 외부데이타타입 [(길이)] [REFERENCE];typedef char asciz[350];EXEC SQL BEGIN DECLARE SECTION; EXEC SQL TYPE asciz IS STRING(350) REFERENCE; asciz catalog_cd[100]; /* ARRAY 변수 정의 */ asciz factor_cd1; asciz factor_cd2; asciz factor_cd3; asciz factor_cd4; asciz factor_cd5;EXEC SQL END DECLARE SECTION;
- 6. PreProcessor의 사용
- #define : 매크로를 정의한다.#include : 현위치에 문장 다음에 나오는 화일을 대치시킨다.#ifdef : 뒤에 따라오는 상수가 이전에 정의되어 있으면 문장 이후에 나오는 source코드를 포함하여 컴파일한다.#ifndef : 뒤에 따라오는 상수가 이전에 정의되지 않았으며 문장 이후에 나오는 source 코드들을 컴파일에 포함시키지 않는다.#endif : #ifdef, #ifndef의 끝을 나타낸다.#elif : #ifdef, #ifndef의 다음 조건을 나타낸다.<예>#define NAME_LEN 20#define PASS_LEN 20VARCHAR uname[NAME_LEN];VARCHAR passwd[PASS_LEN];
- 7. 구조체 변수의 사용
- #define UNAME_LEN 20struct { VARCHAR emp_name[UNAME_LEN] float salary; float commission;} emprec;
- EXEC SQL SELECT ename, sal, comm INTO :emprec FROM EMP WHERE EMPNO = :emp_number;
- 8. Array 호스트 변수의 사용
- char emp_name[10][50]; int emp_number[50]; double salary[50];
- int hi_lo_scores[25][25];
- ARRAY변수의 선언
- char emp_name[20][50]; int emp_number[50]; double salary[50];EXEC SQL SELECT ENAME, EMPNO, SAL INTO :emp_name, :emp_number, :salary FROM EMP WHERE SAL > 1000;
- SELECT ... INTO 문에서 사용시에는 리턴되는 데이타의 최대갯수를 알고 있어야 하고 그 최대 갯수 만큼의 ARRAY를 선언해야 한다.위의 예에서 50개보다 많은 ROW가 리턴된다면 50개 이상의 데이타는 구할 수 없게 된다.다시 SELECT .. INTO문을 실행한다면 또 다시 처음 50개의 ROW만 구해질 것이다.동시에 ORACLE에러가 발생한다.ORA-02112: PCC: SELECT ... INTO return too many rows;
- int emp_number[20];float salary[20];EXEC SQL DECLARE emp_cursor CURSOR FOR SELECT empno, sal FROM emp;EXEC SQL OPEN emp_cursor;EXEC SQL WHENEVER NOT FOUND do break;while(1){ EXEC SQL FETCH emp_cursor INTO :emp_number, :salary; /* fetch된 row의 작업 */ ....}FETCH된 ROW의 갯수sqlca.sqlerrd[2]에 저장되어 있다. 이 값은 각 fetch되는 cursor에 누적된 값이다.EXEC SQL OPEN cursor1;EXEC SQL OPEN cursor2;EXEC SQL FETCH cursor1 INTO :array_of_20;sqlca.sqlerrd[2]의 값 : 20EXEC SQL FETCH cursor2 INTO :array_of_20;sqlca.sqlerrd[2]의 값 : 20 40이 아님.EXEC SQL FETCH cursor1 INTO :array_of_20;sqlca.sqlerrd[2]의 값 : 40EXEC SQL FETCH cursor2 INTO :array_of_30;sqlca.sqlerrd[2]의 값 : 50
- 호스트 ARRAY를 INSERT문의 입력변수로 사용할 수 있다. char emp_name[20][50];int emp_number[50];float salary[50];EXEC SQL INSERT INTO EMP (ENAME, EMPNO, SAL) VALUES(:emp_name, :emp_number, :salary);위에서는 한번의 INSERT문으로 50개의 ROW가 EMP테이블에 추가되었다.ARRAY의 데이타 전체가 유효하지 않다면 “FOR”절을 사용하여 데이타를 선택적으로 INSERT할 수 있다.
- 호스트ARRAY를 UPDATE문의 입력변수로 사용할 수 있다.int emp_number[50];float salary[50];EXEC SQL UPDATE emp SET sal = :salary WHERE EMPNO = :emp_number;ARRAY호스트 변수 중 유효하지 않은 것이 존재하면 "FOR"절을 사용하여 유효한 것만 UPDATE시킬 수 있다.
- int emp_number[50];EXEC SQL DELETE FROM emp WHERE empno = :emp_number;
- int emp_number[50];int dept_number[50];float commission[50];short ind_comm[50];EXEC SQL INSERT INTO emp (empno, deptno, comm) VALUES (:emp_number, :dept_number, :commission INDICATOR :ind_comm);Indicator변수의 array와 호스트변수의 array는 같아야 한다.
- INSERT, EXECUTE, FETCH, DELETE, OPEN, UPDATE 등에서 ARRAY호스트 변수를 사용할 경우 선택적으로 "FOR"절을 사용할 수 있다.특히 INSERT, DELETE, UPDATE문에서는 유용하다.char emp_name[100];short salary [100];int rows_to_insert;rows_to_insert = 25;EXEC SQL FOR :rows_to_insert INSERT INTO emp (ename, salary) VALUES (:emp_name, :salary);/* 100개의 row중에 25개만 insert했다. */"FOR"절은 UPDATE와 INSERT가 동시에 발생되는 TRANSACTION에서는 구현하기가 쉽다.ARRAY호스트 변수를 사용하면서 선택적으로 INSERT, UPDATE해야 하는 프로그램에서는 "FOR"절이 유용하게 사용된다.
- 9. Structure Array 의 사용
- 호스트 변수로 Structure Array를 사용할 수 있다.struct { char emp_name[11]; int emp_number; int dept_number;} emp_rec[3];.......EXEC SQL SELECT ename, empno, deptno INTO :emp_rec[1] FROM emp;.....
- 10. Indicator변수의 사용
- INDICATOR변수는 2바이트 정수형으로 선언되어야 하고 SQL문장에서는 ":"을 앞에 붙여 호스트변수의 바로 뒤에 기술한다.INDICATOR변수는 컬럼의 상태를 가지고 있다.-1 : 선택된 컬럼이 NULL이다.EXEC SQL BEGIN DECLARE SECTION; int emp_number; float salary, commission; short comm_ind;EXEC SQL END DECLARE SECTION;EXEC SQL SELECT SAL, COMM INTO :salary, :commission:ind_comm FROM EMP WHERE EMPNO = :emp_number;if(ind_comm == -1 ) /* commission 컬럼이 NULL이다. */ pay = salary;else pay = salary + commission;
- Indicator변수를 구조체 형식으로 사용할 수 있다.struct { char s_name[32]; int s_id; char grad_date[9];} student_rec;struct { short s_name_ind; short s_id; short grade_date_ind;} student_rec_ind;EXEC SQL SELECT S_NAME, S_ID, GRADE_DATE INTO :student_rec:student_red_ind FROM STUDENT_LIST WHERE S_ID = '95034024';
출처 : http://blog.naver.com/nsjung74/110007853683
'Oracle' 카테고리의 다른 글
Dynamic SQL의 사용 (0) | 2007.01.21 |
---|---|
SQL문 기본 (0) | 2007.01.21 |
proc 파헤치기 (0) | 2007.01.21 |
LINUX + ORACLE 10g 10.1 Install (0) | 2006.06.11 |
Installing Oracle9iR2(9.2.0.4) on RH AS4 (0) | 2006.06.11 |
RECENT COMMENT