글
[오라클 서버에 연결하기]
Net8 Configuration Assistant에서
로컬 네트 서비스 이름 구성 - 추가 - 데이터베이스 /서비스 버전 지정
- 서비스이름(보통 전역데이타베이스명) - 네트워크 프로토콜 (TCP)
- 호스트이름 (오라클 서버의 IP 포트는 그냥 1521)
- 테스트 수행 - 네트서비스이름 (서비스이름과 동일해도 되고, 변경해도 된다.)
- 완료
[xx.pc파일 만들기]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//선언부
EXEC sql BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
VARCHAR ser[20];
long m_empno;
VARCHAR m_ename[20];
double m_sal;
VARCHAR m_hire[20];
EXEC SQL END DECLARE SECTION;
//포함부
EXEC SQL INCLUDE SQLCA;
void main()
{
dasi:
printf("Login Name?");
scanf("%s", uid.arr);
uid.len=strlen(uid.arr);
printf("Password?");
scanf("%s", pwd.arr);
pwd.len=strlen(pwd.arr);
printf("Server Alias?");
scanf("%s", ser.arr);
ser.len=strlen(ser.arr);
//접속부
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd USING :ser;
if(sqlca.sqlcode ==0)
{
printf(" Login Name: %s Success...\n",uid.arr);
}
else
{
printf(" Login Name: %s Failed...\n",uid.arr);
goto dasi;
}
//실행부
printf("EmpNo?");
scanf("%ld", &m_empno);
EXEC SQL SELECT EMPNO,ENAME,SAL,HIREDATE INTO :m_empno,:m_ename,:m_sal,:m_hire
FROM emp WHERE empno=:m_empno;
if(sqlca.sqlcode==0)
{
printf("===================================================\n");
printf(" %ld %s %lf %s\n", m_empno,m_ename.arr,m_sal,m_hire.arr);
printf("====================================================\n");
}
else
{
if(sqlca.sqlcode==1403)
printf(" Not found...\n");
else
printf(" 시스템장애...\n");
}
EXEC SQL COMMIT WORK RELEASE;
fflush(stdin);
getchar();
exit(0);
}
[선행컴파일 : Pro*C/C++]
환경설정 : CPP (또는 C로 선택)
+ : 선행컴파일할 xx.pc 선택
옵션 : cpp로 (c로 선택인 경우 ANSI C로 선택)
선행 컴파일 : xx.cpp로 만들어짐
( SQL문장을 CPP가 실행할 수 있는 코드로 변환시켜줌)
[컴파일]
1. 만들어진 xx.cpp를 Open
2. 컴파일하면 default workspace를 만들거냐고 물어본다. (예)
3. 그리고 Oracle\Ora81\precomp\lib\msvc\oraSQL8.LIB추가한다.
4. 그러면 실행파일이 만들어진다.
[sqlca]
오라클의 SQLCA구조체는 SQL문 실행 후 그 결과값을 위해 만들어진 구조체이다.
· sqlca.sqlcode:4바이트 2진 정수이고, SQL 문의 실행결과를 나타낸다.
0 실행이 정상 종료
1403 NOT FOUND
음수 프로그램 또는 시스템 장애
[주의]
uid.len=strlen(uid.arr);
strlen 함수를 사용하려면 unsigned char는 않되므로 char로 변경시켜주면
에러 않난다.
struct { unsigned short len; unsigned char arr[20]; } uid;
↓
struct { unsigned short len;char arr[20]; } uid;
· 호스트 변수
SQL 문 및 프로그램 문의 양쪽으로부터 참조되는 모든 값에 대해서 선언해야 한다. 호스트 변수의 데이터타입은 선언절에서 호스트 언어를 사용해서 선언해야 하며, 이 때 이 데이터타입은 테이블을 정의할 때에 사용되는 ORACLE 데이터타입과 일치할 필요는 없다.
EXEC sql BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
VARCHAR ser[20];
long m_empno;
VARCHAR m_ename[20];
double m_sal;
VARCHAR m_hire[20];
EXEC SQL END DECLARE SECTION;
EXEC SQL SELECT EMPNO,ENAME,SAL,HIREDATE INTO :m_empno,:m_ename,:m_sal,:m_hire
FROM emp WHERE empno=:m_empno;
printf("Login Name?");
scanf("%s", uid.arr);
uid.len=strlen(uid.arr);
printf("EmpNo?");
scanf("%ld", &m_empno);
표지 변수
emp_sal_indicator =-1; EXEC SQL INSERT INTO emp(empno,sal) VALUES(:emp_number,:emp_salary :emp_sal_indicator);
EXEC SQL SELECT sal INTO :emp_salary :emp_salary_indicator FROM emp
WHERE empno=:emp_no;
if(emp_salary_indicator== -1) // -1 은 NULL을 의미
printf("Employee No %d Salary 0.00\n",emp_no);
else
printf("Employee No %d Salary %f\n", emp_no,emp_salary);
· 호스트 변수로서의 배열
선언 예)
EXEC SQL BEGIN DECLARE SECTION; int emp_number[10]; float emp_salary[10]; char emp_name[10][20]; EXEC SQL END DECLARE SECTION; |
주의사항)
.호스트 배열은 배열 포인터를 선언할 수 없다. (int *p[10];)
. 문자형 변수 이외에는 일차원 배열만 선언할 수 있다.
EXEC SQL SELECT sabun,saname,sajob,sapay,sahire
INTO :sawon_sabun,
sawon_saname,:sawon_sajob,:sawon_sapay,:sawon_sahire
FROM sawon where sajob=:job;
printf("count=%d \n",sqlca.sqlerrd[2]); /* 처리한 행수 */
for(a=0;a<sqlca.sqlerrd[2];a++)
{
printf("%2d %-10s %-10s %8.2f %-16s\n",
sawon_sabun[a],sawon_saname[a], sawon_sajob[a]
,sawon_sapay[a],sawon_sahire[a]);
}
· sqlca.sqlerrd: 4바이트 2진 정수 배열 ORACLE RDBMS의 내부상황
을 파악하기 위해 사용. sqlca.sqlerrd[2]는 INSERT 나
UPDATE 처럼 DML 처리에 대해서 몇 개의 행이 처리 됐는
지를 나타냄
Connected to ORACLE user : CHANG
Job is?부장
count=3
2 한국남 부장 3000.00 88/11/01
13 무궁화 부장 3000.00 96/11/01
17 이성계 부장 2803.00 84/05/01
처리상태 SQLCode=1403 메세지: ORA-01403: 데이터가 없습니다
1.커서의 사용순서
—DECLARE : 커서를 선언한다.
—OPEN : 커서를 활성화 시킨다.
—FETCH : 커서에서 데이터 행을 가져온다.
—CLOSE : 커서 사용을 종료한다.
(sql서버에서는 반드시 deallocate해야한다.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***************************************************************
This is is a sample Pro*C program which uses the FOR option
by inserting records into the EMP table.
***************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
VARCHAR ser[20];
int sawon_sabun;
float sawon_sapay;
char sawon_saname[10];
char sawon_sajob[10];
char sawon_sahire[20];
char sawon_sasex[10];
char job[10];
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE SQLCA;
void main(void)
{
/* log into ORACLE */
strcpy(uid.arr, "CHANG"); /* copy the user name */
uid.len = strlen(uid.arr);
strcpy(pwd.arr, "CHANG"); /* copy the password */
pwd.len = strlen(pwd.arr);
strcpy(ser.arr, "ths");
ser.len = strlen(ser.arr);
//****
EXEC SQL WHENEVERSQLERROR DO return;
//****
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd USING :ser;
printf("Connected to ORACLE user : %s\n", uid.arr);
printf(" JOB is?");
scanf("%s", job);
EXEC SQL DECLARE sawcur CURSOR FOR SELECT sabun,saname,sajob,sapay,sahire,sasex FROM sawon WHERE sajob=:job;
// EXEC SQL WHENEVERSQLERROR DO return;
EXEC SQL OPEN sawcur;
EXEC SQL WHENEVER NOT FOUND DO break;
while(1)
{
EXEC SQL FETCH sawcur INTO
:sawon_sabun,:sawon_saname,:sawon_sajob,:sawon_sapay,:sawon_sahire,:sawon_sasex;
printf(" %3d %-10s %-10s %10.2f %-15s %10s\n",
sawon_sabun,sawon_saname,sawon_sajob, sawon_sapay ,sawon_sahire,sawon_sasex);
}
EXEC SQL CLOSE sawcur;
EXEC SQL COMMIT WORK RELEASE;
fflush(stdin);
getchar();
exit(0);
}
===
u SQLCA의 사용
방법1) EXEC SQL INCLUDE SQLCA; 방법2) EXEC SQL INCLUDE sqlca.h; Pro*C/C++소스 파일에 삽입하면 된다. 방법3) #include <sqlca.h> Pro*C/C++소스 파일이나 생성된 Cpp파일에 삽입하면 된다. 그리고 sqlca.h화일을 VC++의 include Directory에 복사하거나 찾아갈 Directory를 설정해야 한다. |
에러가 검출될 때 어떤 처리를 취해야 할 지를 지정해 주는 문장이다.
EXEC SQL WHENEVER [SQLERROR | SQLWARNING | NOT FOUND] [STOP | CONTINUE | GOTO stmt-label]; |
· SQLERROR : sqlca.sqlcode가 -1인 경우에 설정
· SQLWARNING :sqlca.sqlwarn[0]에 "W"가 설정되어 있는 경우에 설정
· NOT FOUND : sqlca.sqlcode가 1403인 경우에 설정
· STOP : 프로그램을 종료시키고 논리적인 작업단위는 ROLLBACK 된다.
· CONTINUE : sqlca의 상태를 무시하고 프로그램을 계속 진행한다.
· GOTO :지정한 라벨이 붙은 문으로 제어를 옮긴다.
· DO :DO문장 다음에 지정된 함수를 수행한 다음 수행했던 SQL문 다음
문장을 계속하여 실행한다.
ã WHENEVER문장의 범위
WHENEVER문장은 하나의 선언문이기 때문에 이문장의 유효는 물리적인 위치에 의해 정해진다. 일단 WHENEVER문장이 선언되면 그 아래에 위치하는 모든 SQL문들은 WHENEVER문장의 영향을 받는다. 만약 기존의 WHENEVER문장 아래에 새로운 WHENEVER문장이 선언되면 아래 선언된 문장 다음에 나오는 SQL문장들은 새로 선언된 WHENEVER문장의 영향을 받게 된다.
[Pro*C/C++에서 PL/SQL의 블록 사용]
선행컴파일시 옵션 sql검사를 semantics로 해야함
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/****************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
VARCHAR ser[20];
int sawon_sabun;
float sawon_sapay;
char sawon_saname[10];
char sawon_sajob[10];
char sawon_sahire[20];
char sawon_sasex[10];
char name[10];
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE SQLCA;
void main(void)
{
/* log into ORACLE */
strcpy(uid.arr, "CHANG"); /* copy the user name */
uid.len = strlen(uid.arr);
strcpy(pwd.arr, "CHANG"); /* copy the password */
pwd.len = strlen(pwd.arr);
strcpy(ser.arr, "CHANGS");
ser.len = strlen(ser.arr);
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd USING :ser;
printf("Connected to ORACLE user : %s\n", uid.arr);
printf(" Name is?");
scanf("%s", name);
/* SQL문을 PL/SQL의 블럭으로 처리하는 경우 */
EXEC SQL EXECUTE
DECLARE
n NUMBER(3);
BEGIN
n:=0;
if n>0 then
SELECT sabun,saname,sajob,sapay,sahire,sasex INTO
:sawon_sabun,:sawon_saname,:sawon_sajob,:sawon_sapay,:sawon_sahire,:sawon_sasex
FROM sawon WHERE saname=:name;
else
SELECT sabun,saname,sajob,sapay,sahire,sasex INTO
:sawon_sabun,:sawon_saname,:sawon_sajob,:sawon_sapay,:sawon_sahire,:sawon_sasex
FROM sawon WHERE saname='홍길동';
end if;
END;
END-EXEC;
/* 블럭끝*/
printf(" %3d %-10s %-10s %10.2f %-15s %10s",
sawon_sabun,sawon_saname,sawon_sajob,sawon_sapay,sawon_sahire,sawon_sasex);
EXEC SQL COMMIT WORK RELEASE;
fflush(stdin);
getchar();
exit(0);
}
[동적]
실습예문) EXECUTE IMMEDIATE 의 사용
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/****************************************************************/
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR uid[20];
VARCHAR pwd[20];
VARCHAR ser[20];
char select[132];
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE SQLCA;
void main(void)
{
char where[80];
int scode;
/* log into ORACLE */
strcpy(uid.arr, "CHANG"); /* copy the user name */
uid.len = strlen(uid.arr);
strcpy(pwd.arr, "CHANG"); /* copy the password */
pwd.len = strlen(pwd.arr);
strcpy(ser.arr, "CHANGS");
ser.len = strlen(ser.arr);
EXEC SQL WHENEVER SQLERROR STOP;
EXEC SQL CONNECT :uid IDENTIFIED BY :pwd USING :ser;
printf("Connected to ORACLE user : %s\n", uid.arr);
strcpy(select, "UPDATE sawon SET sapay = 2000 WHERE ");
printf("Please enter where clause for the following : \n");
printf("%s", select);
scode = scanf("%s", where);
fflush(stdin);
if(scode == EOF || scode == 0)
{
printf("Invalid entry. \n");
exit(1);
}
strcat(select, where);
printf("%s\n", select);
EXEC SQL EXECUTE IMMEDIATE :select;
printf("%d records updated. \n", sqlca.sqlerrd[2]);
getchar();
EXEC SQL COMMIT WORK RELEASE;
exit(0);
}
'Oracle' 카테고리의 다른 글
[자바오라클스터디] http://www.oraclejava.co.kr 의 PRO*C + CGI강의 (0) | 2007.01.21 |
---|---|
[자바오라클스터디] java로 Pro*C 호출하기 (0) | 2007.01.21 |
ProC에서 Error 처리하기(SQLSTAT,SQLCODE,SQLCA) (0) | 2007.01.21 |
PROC 에서 9I SYNTAX (CASE WHEN,WAIT XX,JOINS) 사용시 PCC-S-02201 발생 (0) | 2007.01.21 |
PROC 에서 외부 환경변수를 받아 들이는 방법 (0) | 2007.01.21 |
RECENT COMMENT