'ORACLE'에 해당되는 글 125건

  1. 2008.06.30 PRO*C 컴파일옵션
  2. 2008.05.20 erwin 도메인 관리 관련 아티클
  3. 2008.04.18 trace파일 만들기
  4. 2007.09.12 OR Mapping
  5. 2007.07.04 시간차이 구하기...
  6. 2007.06.29 MS-SQL 접속 삽질의 날!!!
  7. 2007.03.06 CORE DUMP 해결방법
  8. 2007.03.06 Pro*C란 11
posted by 구름너머 2008. 6. 30. 14:32

'ORACLE' 카테고리의 다른 글

Pro*C 에러처리  (0) 2008.08.21
데이터베이스 export/import  (0) 2008.08.12
erwin 도메인 관리 관련 아티클  (0) 2008.05.20
trace파일 만들기  (0) 2008.04.18
OR Mapping  (0) 2007.09.12
posted by 구름너머 2008. 5. 20. 09:06

'ORACLE' 카테고리의 다른 글

데이터베이스 export/import  (0) 2008.08.12
PRO*C 컴파일옵션  (0) 2008.06.30
trace파일 만들기  (0) 2008.04.18
OR Mapping  (0) 2007.09.12
시간차이 구하기...  (0) 2007.07.04
posted by 구름너머 2008. 4. 18. 14:03

1.trace 파일이 쌓이는 곳
오라클홈/../../admin/SID명/udump
파일명은 보통 sid_ora_process번호.trc 형태인데요...

2.세션ID 찾기
SQL*Plus 로 접속
SQL> !ps
PID TTY TIME COMMAND
29726 pts/tG 0:00 sqlplus

SQL> !ps -ef | grep 29726
nbill1 29727 29726 0 11:07:43 ? 0:00 oracleBILCSS10 (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))

즉, bilcss10_ora_29727.trc 처럼요...

3.trace파일 만들기

SQL> alter session set sql_trace true;

SQL> @쿼리

SQL> alter session set sql_trace false;

4.trace 내용 확인

udump 쪽으로 가서 파일을 찾아서..

$ tkprof /dbms_rs/app/oracle/admin/BILCSS10/udump/bilcss10_ora_29727.trc bilcss10_ora_29727 sort=fchqry,fchcu explain=계정/암호

이런 식으로 해 주면 최종 bilcss10_ora_29727.prf 파일이 뜹니다. 그걸 열어보면 아까 보여주신 자세한 내용이 보일거에요..

'ORACLE' 카테고리의 다른 글

PRO*C 컴파일옵션  (0) 2008.06.30
erwin 도메인 관리 관련 아티클  (0) 2008.05.20
OR Mapping  (0) 2007.09.12
시간차이 구하기...  (0) 2007.07.04
MS-SQL 접속 삽질의 날!!!  (0) 2007.06.29
posted by 구름너머 2007. 9. 12. 14:00

링크1:ORM의 기본적인 개념 및 활용방안

링크2:

출처:http://cafe.naver.com/itleader.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=229

위자료를 바탕으로넘버링과 문자강조를 추가했음.

I.OR Mapping의 개요

. OR Mapping의 정의

-객체지향프로그래밍에서 설계한 클래스와 RDBMS의 Table 간의 Mapping간의 매핑 작업과정

.객체와 테이블 사이의 매핑 필요성

- 객체지향프로그래밍작업에서 OO개념에 맞지않은 RDBMS를 사용하는 경향이 많음

- OODB가 RDB만큼 안정성과 성능을 보장하지 못함



II. 클래스의 Relation 종류

관계

설명

Association

클래스 간의 가장 일반적인 관계로 독자적으로 존재하는 클래스 간의 구조적인 관계

Aggregation

Association의 특별한 형태의 관계로 전체(Whole)와 부분(Part)을 표현

한 클래스가 다른 클래스에 종속적인 포함관계를 나타냄

Composition

Aggregation 관계 중에서 전체와 부분의 생명주기(즉, 생성과 소멸)이 동일한 경우

구현 시 부분(Part)에 해당되는 객체에 대한 생성과 소멸에 대한 특별한 관리가 요구됨

Generalization

클래스간의 상속관계를 표현

공통된 속성이나 오퍼레이션 등을 부모 클래스가 갖고, 각 서브 클래스는 자신만의 고유한 속성과 오퍼레이션을 갖음

III. OR Mapping 절차



.Class를 Table로 변환

- 클래스는 테이블로 매핑

- 클래스의 인스턴스인 객체는 테이블의 로우 하나로 매핑

. Attribute를 Column으로 변환

1).클래스의 속성하나는 0또는 N개의 테이블 칼럼으로 대응

2).영속속성이 아닌 것은 제외

:예) 계산목적으로 사용하는 칼럼, 급여테이블의 실수령액

3) 속성 대 칼럼은 1:1, 1:N, N:1로 매핑가능

-일반적으로 한속성은 한 칼럼으로 대응

-한 속성이 여러 컬럼으로 대응

-여러 속성이 한칼럼으로 대응

:예) 주소속성(우편번호부와 상세번호부로 나뉘어서 2개칼럼으로 대응 가능)

IV. 상속관계(Generalization) 대응시키기

. 상속관계 대응전략

-상속받은 속성을 영속모델에서 어느 테이블에 위치시킬것인가

-Single table, Concrete Table, Class Table방식이 있음

-전체 상속관계에 대해 일률적으로 적용하지 말고 업무 프로세스에 맞게 적합한 방식 선정



. Single table 매핑

1) 매핑방법

-상위 클래스가 Sub 클래스의 모든 속성을 갖는 방법

-서브클래스 속성이 적을 경우에 적합함

-Object ID를 primary key로 설정

2) 장점

- 단순하고 매핑하기 쉬움

- ObjectType이 바뀌더라도 다형성을 지원

- 한 테이블에 자료가 모두 있어서 조인이 필요없고 조회성능 우수

3) 단점

-서브 class에 속성이 추가될때마다 테이블을 변경해야함

-같은 계층에서 결합도 증가(여러 클래스와 하나의 테이블간의 결합도 증가)

-중복자료관리로 공간낭비 발생

- ObjectType 필드추가(서브class구분위해 필요)

- 단일 타입은 수용하나 복수 타입이 되면 표현하기 힘듬(경력사원인데 신입사원으로 채용할경우)



OID(Object ID):객체의 유일성을 보장,테이블에서 Primary key가 된다,테이블에서는 의미없는 속성으로 일반적으로 숫자(Integer)로 표현함

.Concrete Table

1) 매핑방법

-하위클래스가 상위추상클래스의 모든 속성을 갖는 방법

-하위 클래스를 모두 테이블로 매핑

-상위클래스 속성은 하위 테이블에 중복으로 유지

-엔티티별 OID유지

-상위클래스의 속성이 적을 때 적합

2) 장점

-한 테이블에 모든 칼럼이 모두 존재

3) 단점

-상위 클래스 수정이 하위 클래스 테이블까지 모두 변경

: 예) Applicant클래스에 신장이 추가되면 하위 테이블도 모두 추가 필요

-object type이 변경되면 이전타입을 복사하고 새로운 OID할당

:예)신입사원이 경력사원으로 바뀌면 후속작업 과다발생

- 복수 타입을 표현하기 힘들고 데이터 무결성 유지 어려움(이상현상 발생 가능)

- 모든 클래스를 함께 조회할 때 조인이 빈번히 발생



. Class Table

1) 매핑방법

- 상위 클래스와 각 Sub 클래스를 별도의 테이블로 매핑

-클래스의 속성이 그대로 테이블의 속성이 되고 OID가 추가됨

-가장 무난하나 많은 테이블이 생성되어 복잡해지는 단점

2) 장점

-객체기술 개념을 그대로 반영

-다형성을 가장 잘 지원

-상위클래스의 수정이 매우 용이

-새로운 서브클래스의 추가 용이

3) 단점

-테이블의 수가 증가

-조인문이 복잡해져서 조회성능 저하



. 상속관계 매핑 전략 비교

항목

Single

Concrete

Class

조인

단순

보통

어려움

구현

단순

보통

어려움

자료접근

단순

단순

보통

결합도

매우높음

높음

낮음

접근속도

빠름

빠름

보통

다형성

보통

나쁨

좋음

V. 연관관계(Association) 매핑

-연관관계는 테이블사이에서 외래키를 설정해서 구현

. 1:1연관 대응

- 접근의 빈도수가 많은 쪽으로 상대방의 Primary Key가 Foreign Key로 등록

-한테이블로 통합될수 있음



. 1:n연관 매핑

- M 쪽으로 1쪽의 Primary Key를 Foreign Key로 매핑

- 방향성은 Foreign Key가 생성되는 쪽과 상관없이 두 클래스간의 보는 관점의 방향성을 의미



-운향의 방향을 고려하면 TaskOID가 Employee테이블에 외래키로 나와야함

-TaskOID가 여러 개이고 rdbms에서는 하나의 칼럼에 복수값을 허용하지 않음

-따라서 many쪽에 외래키를 둠

. m:n연관관계

-중간에 새로운 연관테이블을 추가함

- 생성된 테이블은 양쪽 테이블의 Primary Key를 갖도록 설계



- Benefit(국민연금)와 Employee는 m:n관계

- 양쪽 테이블의 primay 키를 조합하여 추가테이블 생성



. Aggregation

- 구현상 참조하는 테이블에서 단순 Foreign Key로 참조되는 정도의 의미를 가짐

마. Composition

- 전체와 부분의 생명주기가 동일하므로, Constraint로서 Delete Cascading을 설계하기도 함

VI. OR Mapping 기술전망

-RDB와 객체를 자동으로 연결시켜주는 툴이 개발되어 보다쉽계 변경이 가능함

-Or mapping만으로는 불충분하며 데이터모델에 대한 정규화까지 감안하여 OR매핑을 수행해야함

'ORACLE' 카테고리의 다른 글

erwin 도메인 관리 관련 아티클  (0) 2008.05.20
trace파일 만들기  (0) 2008.04.18
시간차이 구하기...  (0) 2007.07.04
MS-SQL 접속 삽질의 날!!!  (0) 2007.06.29
CORE DUMP 해결방법  (0) 2007.03.06
posted by 구름너머 2007. 7. 4. 18:01

select t2 as from_T, t1 as to_T,
trunc(t*(24),0) as HH,
trunc(mod(t*(24*60) ,60),0) as mi,
round(mod(t*(24*60*60),60),0) as ss
from (
select to_date('20070704161251','yyyymmddhh24miss') - to_date('20070704145000','yyyymmddhh24miss') as t,
to_date('20070704161251','yyyymmddhh24miss') as t1, to_date('20070704145000','yyyymmddhh24miss') as t2
from dual
)

FROM_T TO_T HH MI SS
2007-07-04 오후 2:50:002007-07-04 오후 4:12:51 1 22 51

'ORACLE' 카테고리의 다른 글

trace파일 만들기  (0) 2008.04.18
OR Mapping  (0) 2007.09.12
MS-SQL 접속 삽질의 날!!!  (0) 2007.06.29
CORE DUMP 해결방법  (0) 2007.03.06
Pro*C란  (11) 2007.03.06
posted by 구름너머 2007. 6. 29. 16:11

오류:

[Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]들어오는 TDS(Tabular Data Stream)의 RPC(원격 프로시저 호출) 프로토콜 스트림이 잘못되었습니다. 매개 변수 1(""): 데이터 형식 0x38을(를) 알 수 없습니다.
java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]들어오는 TDS(Tabular Data Stream)의 RPC(원격 프로시저 호출) 프로토콜 스트림이 잘못되었습니다. 매개 변수 1(""): 데이터 형식 0x38을(를) 알 수 없습니다.

1.JDBC 드라이버 개요

http://msdn2.microsoft.com/ko-kr/library/ms378749.aspx

2.JDBC 드라이버 사용

http://msdn2.microsoft.com/ko-kr/library/ms378526.aspx

1.MS-SQL 2000

Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

2.MS-SQL 2005

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

3.MS-SQL 2000 Connection 맺기

String connectionUrl = "jdbc:microsoft:sqlserver://localhost:1433;"
+ "databaseName=AdventureWorks;SelectMethod=cursor;user=MyUserName;password=*****;";
Connection con = DriverManager.getConnection(connectionUrl);

4.MS-SQL 2005 Connection 맺기

String connectionUrl = "jdbc:sqlserver://localhost:1433;"
+ "databaseName=AdventureWorks;SelectMethod=cursor;user=MyUserName;password=*****;";
Connection con = DriverManager.getConnection(connectionUrl);

2005버전에서 2000버전의 JDBC를 사용할 경우

connection 접속은 정상이나 select시 위와 같은 에러가 나네요..

역시..드라이버 문제...

<해결방법>

1--->2로

3--->4로 수정 후

유첨의 jdbc드라이버를 classpath에 추가하면 문제 해결되었습니다.^^

첨부:2005용 JDBC 드라이버입니다.

sqljdbc.jar

'ORACLE' 카테고리의 다른 글

OR Mapping  (0) 2007.09.12
시간차이 구하기...  (0) 2007.07.04
CORE DUMP 해결방법  (0) 2007.03.06
Pro*C란  (11) 2007.03.06
sqlplus 사용을 고급화하기.  (0) 2007.01.12
posted by 구름너머 2007. 3. 6. 10:26
BULLETIN CATEGORY BULLETIN TOPIC: PRECOMPILER      
: (pro*c) CORE DUMP 해결방법 

pro*c로 Precompile시에 에러 메세지 없이 Core Dump가 발생하면서  
작업이 중단되는 경우가 있다. 그 이유는 다음과 같다. 아래의 경우는 모든 경우에 적용되는 것은 아니다. Compiler에 따라 아무 문제 없이 실행되는 경우도 있다.  
그러므로 debug를 하여서 어느 부분에서 Core Dump가 발생하는지 확인후 조치를 해야한다.  
   
1.syntax에러가 있는 경우로, 예를 들면  
1)WHERE ENAME = MILLER ' ; 와 같이 따옴표가 빠져 있는 경우  
2)SQL query 문을 잘못 사용한 경우 등...  
   
2.EXEC SQL VAR 변수명 IS STRING[크기];  
에서 STRING 크기를 지정하지 않은 경우  
   
3.함수값을 retrun할 때 return()을 사용한 경우. 이때는 return 으로 바꾸  
면 해결 된다. 모든 경우에 적용되는 것은 아니고 compiler에 따라 이러한 경우가  
생기는 경우가 있다.  
   
4.typedef 를 이용하여 선언한 변수가 struct 의 member로 사용되는 경우  
   
5.mode=oracle이 아닌 mode=ansi로 컴파일 할 때 core dump가 발생하는 경우가 있다.  
   
6.환경변수 NLS_LANG이 Korean_Korea.KO16KSC5601과 같이 한글 characterset  
을 사용할 때 core dump가 떨어지는 경우가 있다. 이 때는 American_America.US7ASCII 로 변경하면 된다.  
   
7.#define에서 기술한 매크로의 이름이나 그 길이가 매우 길 경우  
   
8.주석문에서 /*+ 가 있을 경우, 즉 /* 다음에 바로 플러스기호(+)가 나올  
경우  
   
9.typedef로 선언한 변수가 너무 많을 경우.  
   
10.string concatenation을 implicit하게 처리할 때, 즉  
   
printf("%s\n","hello""world");  
   
와 같이 따옴표를 그냥 붙여서 concatenation 할 때  
   
  1. Precompile 시에 주는 옵션에서 SQLCHECK=FULL
또는 SQLCHECK=SEMANTICS를 사용하는 경우에 Core Dump가 떨어지는 경우가 있는데, 프로그램 안에서 Pl/Sql Block이나 Stored Procedure Call을 하지 않는 경우라면 Sqlcheck 옵션과 Userid 옵션을 삭제하고 Precompile을 하면 된다.  
 
12.Sql Statement의 길이가 길 때 발생하는 경우가 있다. 이 때에는 View  
등을 이용하여 Sql Statement의 길이를 줄이도록 한다.  
   
13.Cursor 선언에서 Column 갯수가 많을 때 발생하는 경우로, 이 때에는  
Cursor를 여러개를 선언해서 Select하는 Column을 분리 하도록 한다. 

'ORACLE' 카테고리의 다른 글

시간차이 구하기...  (0) 2007.07.04
MS-SQL 접속 삽질의 날!!!  (0) 2007.06.29
Pro*C란  (11) 2007.03.06
sqlplus 사용을 고급화하기.  (0) 2007.01.12
오라클 Role 관리  (0) 2006.12.18
posted by 구름너머 2007. 3. 6. 10:23

http://cafe.naver.com/foryouweb/975

1.1 Pro*C란?

ORACLE RDBMS에 준비된 Pro*C툴은, SQL문을 포함한 C 프로그램을, ORACLE 데이터베이스내에 있는 데이터에 접근과, 조작을 할 수 있는 C 프로그램으로 변환하기 위한 것이다. Pro*C는 프리컴파일러이기 때문에, 입력 파일 내에 있는 EXEC SQL 문을 적당한 ORACLE 콜로 변환해서 출력 파일을 작성한다. 그 다음 이 출력 파일을 C 프로그램에 대한 통상의 방법으로 컴파일하고 링크해서 실행모듈을 작성한다.

1.2 개요

Pro*C 툴을 사용하면 프로그램머는 통상의 프로그래밍 과정에 덧붙여서 별도의 처리를 수행 할 필요가 생긴다. 그러나 별도의 처리를 추가함으로써, 프로그램머에 도움이 되는 상당량의 작업을 Pro*C 툴이 수행하게 된다.

 C 프로그램을 작성해서 기동할 때의 통상의 작업 순서는 다음과 같다.       1. C 프로그램을 작성한다.       2. 프로그램을 컴파일해서 오브젝트 파일을 작성한다.       3. 오브젝트 파일을 링크해서 실행 가능한 파일을 작성한다.       4. 프로그램을 실행한다.  프로그래머가 소스프로그램에 Pro*C 문을 짜넣는 경우는, 위에서 기술한 순서에    한가지 처리가 더 추가된다.       1. Pro*C 프로그램을 작성한다.       2. Pro*C를 이용해서 프로그램을 프리컴파일 한다.       3. 프로그램를 컴파일해서 오브젝트 파일을 작성한다.       4. 오브젝트 파일을 링크해서 실행 가능한 파일을 작성한다.       5. 프로그램을 실행한다.

1.2.1 C 커맨드 및 SQL 문의 혼합

올바른 SQL 문이면 C 프로그램에서 실행할 수 있다. Pro*C 프로그램에서는 필수의 구성요소나 문장이 몇 개정도 있는 것 외에 기본적인 "지정순서"가 있지만, C 프로그램내의 어디에 배치해도 좋다

1.2.2 커맨드의 접두사 EXEC SQL

SQL 문을 호스트 언어에 포함시킴으로써, 발생할 수 있는 언어상의 장애를 최소화하기 위해서, 모든 SQL 문에는 EXEC SQL 이라고 하는 접두사를 붙인다.

1.2.3 커맨드의 접두사 EXEC ORACLE

대부분의 Pro*C 문에는 EXEC SQL 이라는 접두사를 붙이지만 EXEC ORACLE 이라는 접두사를 붙인문도 있다. 이들의 문은 SQL과는 호환성이 없고, ORACLE 프리컴파일러 특유의 것이다.

1.2.4 SQL 실행문 및 선언문

Pro*C 프로그램에 포함되어 있는 SQL 문은, 실행문 혹은 선언문중의 하나로 분류할 수 있다. 실행문 혹은 선언문에 관계없이 문에는 모두 EXEC SQL 이라는 접두사가 붙는다.

 실행문

실제로 데이터베이스에 대한 콜을 행성하는 SQL 문이다. 데이터조작문(DML), 데이터정의문(DDL), 데이터제어문(DCL) 등이 있다. SQL 실행문을 실행한 후, SQLCA(SQL 통신영역)에는 일련의 리턴코드가 저장된다.

논리적인 작업단위는, 최초의 SQL 실행문을 실행함으로써 시작된다. 그러므로 CONNECT, COMMIT, ROLLBACK WORK 문의 다음에 첫 번째로 나타나는 SQL 실행문부터 논리적인 작업단위가 새롭게 시작된다.

 선언문

코드를 생성하지 않기 때문에 논리적인 작업단위에 영향은 없다.

1.2.5 Pro*C 프로그램의 구성

Pro*C 프로그램은 2개의 부분으로 구성되어 있고, Pro*C의 처리에는 양자가 모두 필요하다.

 어플리케이션 프롤로그

변수를 정의하고, Pro*C 프로그램을 위한 일반적인 준비를 수행한다.

 어플리케이션 본체

ORACLE 데이터를 조작하기 위한 INSERT나 UPDATE 등의 SQL 문을 포함한다. Pro*C가 처리시 필요로 하는 코드의 전후에 어떠한 C 코드를 지정해도 상관없다.

2.1 어플리케이션 프롤로그

** 선언절

** INCLUDE SQLCA 문

 ** CONNECT 문

2.1.1 선언절 ( 2.0 버젼 이후 없어도 상관 없음 )

C 프로그램내에서 사용된 모든 호스트 변수를 선언한다. 선언절은 아래의 문으로 시작한다.

EXEC SQL BEGIN DECLARE SECTION;

아래의 문으로 종료한다.

EXEC SQL END DECLARE SECTION;

위 두 개의 문 사이에 허용되는 문은 호스트 변수 또는 표지 변수를 선언하는 문 뿐이다.

**호스트 변수

SQL 문 및 프로그램 문의 양쪽으로부터 참조되는 모든 값에 대해서 선언해야 한다. 호스트 변수의 데이터타입은 선언절에서 호스트 언어를 사용해서 선언해야 하며, 이 때 이 데이터타입은 테이블을 정의할 때에 사용되는 ORACLE 데이터타입과 일치할 필요는 없다.

EXEC SQL BEGIN DECLARE SECTION;

int pempno; /* 사번 */

char pname[11]; /* 성명 */

int pdeptno; /* 부서 */

EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT deptno, ename

INTO :pdeptno, :pname

FROM emp

WHERE empno = :pempno;

호스트 변수의 조건

~선언절에서 명시적으로 선언한다.

~선언한 대로 영어 대문자/소문자의 포맷을 사용한다.

~SQL 문에서는 앞에 콜론(:)을 붙인다.

~C 문에서는 앞에 콜론을 붙이지 않는다.

~SQL의 예약어를 사용해서는 안된다.

~상수를 사용할 수 있는 곳에서만 사용한다.

~표지 변수가 붙어 있어도 상관없다.

**표지 변수

선언절에서 선언된 호스트 변수에 1대 1로 대응되는 임의 선택 변수이다. 표지 변수는 주로 널 값을 취급하는데 유효하다

표지 변수의 조건

~선언한 대로 영어 대문자/소문자의 포맷을 사용한다.

~2바이트 정수로써 선언해야 한다.

~SQL 문에서는 앞에 콜론(:)을 붙인다.

~C 문에서는 앞에 콜론을 붙이지 않는다.

~SQL의 예약어를 사용해서는 안된다.

~SQL 문 내에서는 대응하는 입력 호스트 변수를 앞에 붙여 사용한다.

호스트 변수로서의 포인터 선언

포인터 변수는 C에서 통상적으로 행하는 방법으로 선언함으로써, 선언절내에서 사용할 수 있다.

EXEC SQL BEGIN DECLARE SECTION;

int I, j, *intptr;

char *cp;

EXEC SQL END DECLARE SECTION;

SQL 문에서 사용하는 경우는 별표가 아닌 콜론(:)을 변수명 앞에 붙인다.

SELECT intfield INTO :intptr FROM…;

VARCHAR 의사타입의 선언

Proc*C에서는 VARCHAR 의사타입을 사용할 수 있으므로, 가변 길이의 문자열을 처리할 수 있다. VARCHAR 의사타입은 선언절에서 참조할 뿐이고, 확장된 C 타입 또는 사전에 선언된 구조라고 생각할 수 있다.

EXEC SQL BEGIN DECLARE SECTION;

VARCHAR jobDesc[40];

EXEC SQL END DECLARE SECTION;

이 선언은 다음의 구조체로 확장할 수 있다.

struct {    unsigned short int len;    unsigned char arr[40];} jobDesc;

2.1.2 SQL 통신영역의 선언

어플리케이션 프로롤로그내에서 SQL 통신영역(SQLCA)에 대한 참조를 포함시킴으로써 각 Pro*C 프로그램에서 발생하는 상황처리를 가능하게 하는데, 유저는 다음의 문을 지정하면 된다.

EXEC SQL INCLUDE SQLCA;

Pro*C는 프리컴파일시에 SQLCA 파일의 위치를 알아야 한다. 때문에 유저는 다음의 3가지중 하나를 선택해야 한다.

 ~~"INCLUDE = " 커맨드 라인 옵션을 사용한다.

 ~~Pro*C가 파일을 SYS$ORACLE:SQLCA(VMS의 경우)처럼 공동의 OS영역에서 발견할 수 있도록 파일의 정식 명칭을 지정한다.

 ~~PCC를 호출할 디렉토리 또는 디스크에 SQLCA를 카피한다.

SQLCA는 다음과 같은 정보를 포함하고 있다.

 경고 플래그와 처리상황에 관한 정보

 에러 코드

 진단 정보

디폴드 값으로서, Pro*C는 가능한한 에러를 무시하고 처리를 속행시킨다. SQLCA내에 포함된 변수를 사용함으로써, 프로그래머는 각각의 환경에서 실행해야 할 처리를 제어할 수 있다.

2.1.3 ORACA(SQLCA에 대한 확장)

ORACA를 사용하기 위해서는 EXEC SQL INCLUDE을 사용해서 ORACA의 정의를 참조하거나 커맨드라인 옵션 또는 EXEC ORACLE OPTION에서 ORACA = YES 옵션을 선택하여야 한다.

2.1.4 ORACA 내의 정보

  현재의 SQL 문의 텍스트(orastxt)  ORACLE RDBMS가 해석한 문의 내용을 조사할 수 있다. (CONNECT, FETCH, COMMIT등 은 제외)  ~에러가 있는 파일의 이름(orasfnm)  ~에러가 있는 행의 번호(oraslnr)  ~SQL 문 보존 플래그(orastxtf)        이 플래그를 설정함으로써 어느 조건으로 문을 보존할 지를 선택할 수 있다.          0. 디폴트값. SQL 문을 보존하지 않는다.          1. SQLERROR가 있는 SQL 문 만을 보존한다.          2. SQLERROR 및 SQLWARN이 있는 문을 보존한다.          3. SQL 문을 전부 보존한다.    ~DEBUG 처리의 사용 허가 플래그         이 플래그는 0이나 1을 설정할 수 있다.          1을 설정한 경우는 모든 DEBUG 처리를 사용할 수 있다.      커서 캐쉬 검사(orahchf)

2.1.5 ORACLE에의 접속

EXEC SQL CONNECT :oracleid IDENTIFIED BY :oraclepassword;

 CONNECT 문은 Pro*C 프로그램 내에서 실행된 최초의 SQL 실행문이어야 한다. 선언문과 C 코드만을 논리적으로 CONNECT 문 앞에 놓을 수 있다. 패스워드를 따로 지정하는 경우는 ORACLE의 유정명과 ORACLE의 패스워드의 양쪽에 대해 호스트 변수를 사용해야 한다.

 양쪽의 호스트 변수를 고정길이 문자열 또는 가변길이 문자열 중의 하나로 선언해야 한다.

 CONNECT 문을 수행하기 전에 양쪽의 호스트 변수를 초기화켜 놓아야 한다.

 CONNECT는 프로그램의 최초의 실행문이지만 논리적인 작업단위의 시작은 아니다.

2.2 어플리케이션 본체

어플리케이션 본체에는 ORACLE 데이터베이스 내에 보존된 데이터를 쿼리하고 조작하기 위한 SQL 문이 들어 있다. 이러한 문은 데이터 조작문이라고 한다. 또한 어플리케이션 본체에는 데이터 정의문이 포함되며 이것은 테이블, 뷰, 인덱스등의 데이터 구조를 작성하거나 정의하기 위해 사용한다.

 ~DECLARE STATEMENT 문

 ~DECLARE DATABASE 문

 ~EXEC ORACLE 옵션

2.3 Pro*C 예제 프로그램

/* 예제 #1 */ORACLE의 로그온과 로그오프#include /***************************************************************This is sample Pro*C program which will log onto a database asscott/tiger.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    EXEC SQL COMMIT WORK RELEASE;            /* log off database */    exit(0);}/* 예제 #2 */    테이블의 작성#include /***************************************************************This is is a sample Pro*C program which will create a table.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    EXEC SQL CREATE TABLE Emp_TEST        (empno     number        ,ename     char(15)        ,job        char(10)        ,mgr       number        ,hiredate    date        ,sal         number        ,deptno     number);    printf("Table emp_test created. \n");    EXEC SQL COMMIT WORK RELEASE;    exit(0);}/* 예제 #3 */      행을 삽입하기 위한 값의 입력지시#include /***************************************************************This is is a sample Pro*C program which will insert recordsinto the EMP table by prompting the user for values to be entered.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    int empno;    VARCHAR ename[15];    VARCHAR job[10];    float sal;    int deptno;EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    int sret;                                   /* return code from scanf */    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n\n\n", uid.arr);    while(1)    {        printf("Enter employee number(or 0 to end) : ");        sret = scanf("%d", &empno);        if( sret == EOF !! sret == 0 !! empno == 0 )            break;                                      /* terminate loop */        printf("Enter employee name : ");        scanf("%s", ename.arr);        ename.len = strlen(ename.arr);                /* set the name size */        printf("Enter employee's job : ");        scanf("%s", job.arr);        job.len = strlen(job.arr);                     /* set the job size */        printf("Enter employee salary : ");        scanf("%f", &sal);        printf("Enter employee deptno : ");        scanf("%d", &deptno);        EXEC SQL INSERT INTO EMP                  (empno                  ,ename                  ,job                  ,sal                  ,deptno)        VALUES (:empno                  ,:ename                  ,:job                  ,:sal                  ,:deptno);        EXEC SQl COMMIT WORK;        printf("Employee %s added. \n\n", ename.arr);    }    EXEC SQL COMMIT WORK RELEASE;            /* log off database */    exit(0);}/* 예제 #4 */    배열을 이용한 삽입#include /***************************************************************This is is a sample Pro*C program which uses the FOR optionby inserting records into the EMP table.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    int empno[100];    VARCHAR ename[100][15];    VARCHAR job[100][10];    VARCHAR hiredate[100][9];    float sal[100];    int deptno[100];    int loop;EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;FILE *fp;void main(void){    int i;    int fsret;    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                        /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                        /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR GOTO errrpt;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n\n\n", uid.arr);    if((fp = fopen("test.dat", "r")) == NULL)    {        printf("Error opening file test.dat \n");        exit(1);    }    while(1)    {        for(i = 0; i < 100 ; i++)        {            fsret = fscanf(fp, "%d %s %s %s %f %d",                        &empno[i ], ename[i ].arr, job[i ].arr, hiredate[i ].arr,                        &sal[i ], &deptno[i ]);            if(fsret == EOF)                break;            if(fsret == 0)            {                printf("Incompatible field on the line. \n");                exit(1);            }            ename[i ].len = strlen(ename[i ].arr);            job[i ].len = strlen(job[i ].arr);            hiredate[i ].len = strlen(hiredate[i ].arr);        }        loop = i;        EXEC SQL FOR :loop            INSERT INTO EMP(empno, ename, job, hiredate, sal, deptno)            VALUES(:empno, :ename, :job, :hiredate, :sal, :deptno);        EXEC SQL COMMIT WORK;        printf("%d rows inserted. \n", sqlca.sqlerrd[2]);        if(loop < 100)            break;    }    printf("File test.dat loaded. \n");    EXEC SQL WHENEVER SQLERROR CONTINUE;    EXEC SQL COMMIT work RELEASE;    exit(0);    errrpt:        printf("\n %70s \n", sqlca.sqlerrm.sqlerrmc);        EXEC SQL ROLLBACK WORK RELEASE;        exit(1);}   /* 예제 #5 */         갱신에 사용하기 위한 값의 입력지시#include /***************************************************************This is is a sample Pro*C program which will prompt the userfor an employee name and will display thr current sal and commfields for that employee.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    int empno[10];    float sal, comm;    short sali, commi;EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    int sret;    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR STOP;    EXEC SQL WHENEVER NOT FOUND STOP;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    printf("Enter employee name to update : ");    scanf("%s", ename.arr);    ename.len = strlen(ename.arr);    EXEC SQL SELECT SAL, COMM                  INTO  :sal, :comm                  FROM EMP                 WHERE ENAME = :ename;    printf("Employee : %s   sal : %6.2f   comm : %6.2f \n", ename.arr, sal,            comm);    printf("Enter new salary : ");    sret = scanf("%f", &sal);    sali = 0;    if(sret == EOF !! sret == 0) sali = 0;    printf("Enter new commision : ");    sret = scanf("%f", &comm);    commi = 0;    if(sret == EOF !! sret == 0) commi = -1;    EXEC SQL UPDATE EMP                 SET     SAL = :sal:sali,                         COMM = :comm:commi                WHERE ENAME = :ename;    printf("Employee %s updateed. \n", ename.arr);    EXEC SQL COMMIT WORK RELEASE;    exit(0);}   /* 예제 #6 */       배열을 이용한 갱신#include /***************************************************************This is is a sample Pro*C program which updates using hostvariable arrays. The arrays will be loaded with valuesfrom operator input.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    int empno[100];    float sal[100];    int loop;EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    int i, sret;    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR GOTO errrpt;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    while(1)    {        for(i = 0; i < 100; i++)        {            printf("Enter employee number (or 0 to end loop) : ");            sret = scanf("%d", &empno[i ]);            if(sret == EOF !! sret == 0 !! empno[i ] == 0) break;            printf("Enter updated salary : ");            sret = scanf("%f", &sal[i ]);            if(sret == EOF !! sret == 0)            {                printf("Error in entry; terminating at this empno. \n");                break;            }        }        if(i == 0) break;        loop = i;        EXEC SQL FOR :loop            UPDATE EMP SET SAL = :sal            WHERE EMPNO = :empno;        EXEC SQL COMMIT WORK;        printf("%d rows updated. \n", sqlca.sqlerrd[2]);    }    printf("Update program complete. \n");    EXEC SQL WHENEVER SQLERROR CONTINUE;    EXEC SQL COMMIT WORK RELEASE;    exit(0);errrpt:    printf("\n %70s \n", sqlca.sqlerrm.sqlerrmc);    EXEC SQL ROLLBACK WORK RELEASE;    exit(1);}/* 예제 #7 */    배열을 이용한 선택#include /***************************************************************This is is a sample Pro*C program which selects using hostvariable arrays.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    int empno[100];    VARCHAR ename[100][15];    float sal[100];EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    long num_ret;    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR GOTO errrpt;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);     EXEC SQL DECLARE C1 CURSOR FOR        SELECT  EMPNO, ENAME, SAL          FROM   EMP;    EXEC SQL OPEN C1;    EXEC SQL WHENEVER NOT FOUND GOTO endloop;    num_ret = 0;    while(1)    {        EXEC SQL FETCH C1 INTO : empno, :ename, :sal;        print_rows(sqlca.sqlerrd[2] - num_ret);        num_ret = sqlca.sqlerrd[2];    }endloop:    if(sqlca.sqlerrd[2] - num_ret > 0)        print_rows(sqlca.sqlerrd[2] - num_ret);    printf("\n\nProgram complete. \n");    EXEC SQL WHENEVER SQLERROR CONTINUE;    EXEC SQL COMMIT WORK RELEASE;    exit(0);errrpt:    printf("\n %70s \n", sqlca.sqlerrrm.sqlerrmc);    EXEC SQL ROLLBACK WORK RELEASE;    exit(1);}int print_rows(long n){    long i;    printf("\n\nEmployee number\tEmployee Name\tSalary\n");    printf("\n\n---------------\t-------------\t------\n");    for(i = 1; i < n; i++)        printf("%15d\t%13s\t%6.2f\n", empno[i ], ename[i ].arr, sal - i);    return 0;}    /* 예제 #8 */기존의 테이블로부터 행의 삭제#include /***************************************************************This is is a sample Pro*C program which will delete a rowfrom the emp table by prompting for an employee number.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    int empno;EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR STOP;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    scanf("%d", &empno);    EXEC SQL DELETE FROM EMP WHERE EMPNO = :empno;    EXEC SQL COMMIT WORK RELEASE;    printf("Employee number %d dropped. \n", empno);    exit(0);}

3.1 쿼리의 구성

Pro*C를 사용해서 작성하는 쿼리에는 다음에 나타낸 구를 지정한 어떠한 SELECT 문도 사용할 수 있다.

SELECT

INTO

FROM

WHERE

CONNECT

UNION

INTERSECT

MINUS

GROUP BY

HAVING

ORDER BY

3.1.1 입력 호스트 변수

WHERE 구 내의 호스트 변수는 입력 호스트 변수라고 부른다.

3.1.2 출력 호스트 변수

INTO 구 내의 호스트 변수는 출력 호스트 변수라고 부른다.

3.2 1개의 행 만을 리턴하는 쿼리

쿼리가 오직 1개의 행 만을 리턴하는 것을 알고 있는 경우는, SELECT 리스트 내의 항목과 같은 수의 출력 호스트 변수를 지정한 INTO 구를 사용한다.

3.3 복수의 행을 리턴하는 쿼리(커서의 사용법)

쿼리가 복수의 행을 리턴하는 경우, 혹은 몇 개의 행이 리턴됐는지 모를 경우는, SELECT 문과 함께 커서를 사용해야 한다.

커서는 ORACLE 및 Pro*C가 사용하는 작업 영역이고, 이 속에 쿼리의 결과가 포함된다. 커서는 1개의 SELECT문에 대응하고, 쿼리가 변화할 때마다 반복해서 실행된다. 커서는 선언되어야 하며, 데이터의 처리를 위해서 커서를 사용할 때는 아래의 4개의 커서 커맨드를 사용한다.

 DECLARE CURSOR

 OPEN CURSOR

 FETCH

 CLOSE CURSOR

커서를 "OPEN" 한 후 그 커서를 사용해서, 그것에 대응한 쿼리의 결과로서 얻어진 여러 행을 검색 할 수 있다. 쿼리 기준을 만족한 행은 모두 집합의 형식을 취하고, 이것을 커서의 실효집합이라고 부른다. 쿼리가 종료하면 커서를 "CLOSE" 한다.

3.3.1 DECLARE CURSOR 문

DECLARE CURSOR 문에서는 커서를 정의한다.

EXEC SQL DECLARE cursor_name CURSOR FOR

SELECT … FROM …

이 구문은 실제로 다음과 같이 사용한다.

EXEC SQL DECLARE C1 CURSOR FOR

SELECT ename, empno, job, sal

FROM emp

WHERE deptno = :deptno;

커서를 참조한는 SQL 문을 사용하기 전에 반드시 이커서에 대응하는 DECLARE CURSOR 문을 실행해야 하며, Pro*C는 선언되지 않은 커서에 대한 참조를 해석할 수 없다.

프로그램 내에는 복수의 커서를 사용할 수 있으며 동일 프로그램 내에서 같은 이름의 커서를 지정해서는 안된다.

3.3.2 OPEN CURSOR

커서를 OPEN 함으로써 쿼리가 판정되고, 행의 실효집합이 식별된다.

EXEC SQL OPEN cursor_name;

커서는 OPEN 상태에서 실효집합 최초의 행 직전에 위치된다. 그러나, 실제로 이 시점에서는 아직 어느 행의 검색도 행하지 않는다.

커서를 일단 OPEN 하면 다시 OPEN 하지 않는한, 이 커서의 입력 호스트 변수는 새로이 체크되지 않는다.

3.3.3 실효집합의 행의 검색(FETCH 문)

FETCH 문에서는 실효집합의 행을 읽어 들이고, 결과를 얻을 출력 호스트 변수의 이름을 지정한다.

EXEC SQL FETCH cursor_name INTO :hostvar1, :hostvat2 …;

이 구문은 실제로 다음과 같이 사용된다.

EXEC SQL FETCH C1 INTO :pename, :pempno, :pjob, :psal;

처음으로 커서를 실행하면, 커서는 실효집합의 이전 위치에서 실효집합의 첫째 행으로 이동하며 이 행이 현재의 행이 된다. 커서는 실효집합의 다음행으로만 진행하며 앞에 검색한 행으로 되돌아 가기 위해서는 커서를 CLOSE 하고 다시 오픈해야 한다.

3.3.4 CLOSE CURSOR 문

실효집합 행의 검색을 종료한 후 커서를 CLOSE 함으로써, 커서의 OPEN 상태를 유지하기 위해서 사용된 자원을 해제한다.

EXEC SQL CLOSE cursor_name;

CLOSE 한 커서에 대해서는 검색을 행할 수 없다.

3.4 예제 프로그램

/* 예제 #9 */   WHERE 구에 의한 쿼리#include /***************************************************************This is is a sample Pro*C program which will display all thesalesman in the employee table.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    float sal, comm;    char ename[11];EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR STOP;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    EXEC SQL DECLARE C1 CURSOR FOR        SELECT ENAME, SAL, COMM          FROM EMP        WHERE JOB = 'SALESMAN';    EXEC OPEN C1;    EXEC SQL WHENEVER NOT FOUND STOP;    printf("SALESMAN NAME\t\tSALARY\t\tCOMMISSION\n\n");    for( ; ; )    {        EXEC SQL FETCH C1 INTO :ename, :sal, :comm;        printf("%-10s\t\t%6.2f\t\t%6.2f \n", ename, sal, comm);    }    EXEC SQL CLOSE C1;    EXEC SQL WHENEVER SQLERROR CONTINUE;   /* don't trap errors */    EXEC SQL COMMIT WORK RELEASE;    exit(0);}

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

ORACLE의 기능에 의하여, 유저의 작업 모두가 실행하면 바로 COMMIT되는 것이 아니다. 다시말해서 ORACLE에서는 COMMIT 을 행하기 전에 모든 트랜잭션이 완료되어 있는지를 유저 자신이 확인하도록 되어 있다.

ORACLE은 BEFORE 이미지 파일을 사용하여, 데이터베이스의 일관성을 보호하고 있다. BEFORE 이미지 파일에는 트랜잭션이 시작하기 전의 상태로 데이터베이스의 블록이 보존된다. 상황에 따라 이들의 블록이 데이터베이스 파일에 다시 기록되어, 트랜잭션에 의해 변경된 부분이 변경 전의 상태로 되돌려 진다. 이 같은 처리는 다음과 같은 경우 발생한다.

  유저에 의한 ROLLBACK WORK  유저 프로세스 내의 ORACLE로부터의 이상 종료  프로세스간의 데드록  시스템 장애(H/W OR S/W)

4.1 COMMIT WORK

COMMIT WORK 문은 현재 진행 중인 논리적인 작업단위를 종료하게 하고, 이 작업단위 내에서 행해진 변경을 모두 확정한다.

EXEC SQL COMMIT WORK [RELEASE];

RELEASE 옵션 파라미터는 프로그램이 소유하고 있는 자원을 모두 리턴하고, 데이터베이스에서 로그로프한다.

4.2 ROLLBACK WORK

ROLLBACK WORK 문은 현재 진행 중인 논리적인 작업단위를 종료하게 하고, 이 작업단위에서 행한 변경을 취소한다.

EXEC SQL ROLLBACK WORK [RELEASE];

유저는 RELEASE 옵션을 사용해서 최후의 작업단위를 반드시 명시적으로 COMMIT 또는 ROLLBACK해야 한다.

5.1 표지 변수에 리턴된 값의 사용

어느 호스트 변수에도 임의 선택 변수인 표지 변수를 대응시킬 수 있다. 이 표지 변수를 사용하면 각각의 필드 값이 어떤 경우인지 알 수 있다.

값      의미━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0    리턴되는 값은 호스트 변수에 보존된다. 이것은 널도 아니고,      절사도 되지 않는다.-1   리턴된 값은 널이다. 호스트 변수의 값은 정의되지 않는다.20   리턴된 값은 절사되어 있다. 호스트 변수의 폭이 충분하지 않다.      표지 변수에 설정된 값은 절사되기 전의 폭이다

5.2 SQLCA의 구조

SQLCA 는 프로그램의 실행에 관한 정보를 교환하기 위해, 모든 Pro*C 프로그램에서 사용한다. SQLCA는 각각의 트랜잭션에 대해서 널 값의 무시여부, 쿼리를 시작하고 나서 데이터의 변경 여부등을 표시하므로, 프로그래머는 각각의 데이터 상태를 확인할 수 있다.

5.2.1 SQLCA를 참조하는 타이밍

SQLCA는 각 SQL 실행문의 실행 때마다 갱신된다. 따라서 프로그래머는 각 실행문 뒤에서 SQLCA를 검색해야 한다. 특히 각 DML 문 뒤에서는 SQLCA를 검색할 필요가 있다. 이는 테이블 속의 일부의 행만을 처리한 뒤에 INSERT 및 UPDATE 문이 실패한다면, 유저는 데이터베이스을 어떤 일관성 있는 상태로 회복하기 위해 ROLLBACK WORK 커맨드를 실행해야 하기 때문이다.

WHENEVER 문을 사용하면 이상 상태를 검출하고 그 상태에 따라 적절히 동작을 지정할 수 있다. 다음은 WHENEVER 문의 디폴트 값이다.

EXEC SQL WHENEVER anyerror CONTINUE;

5.2.2 SQLCA의 각 요소의 의미

struct sqlca {      char sqlcaid[8];      long sqlcabc;      long sqlcode;      struct {             unsigned short sqlerrml;             char   sqlerrmc[70];       } sqlerrm;      char sqlerrp[8];      long sqlerrd[6];      char sqlwarn[8];      char sqlext[8];};struct sqlca sqlca;  *sqlca.sqlcode   4바이트 2진 정수이고, SQL 문의 실행결과를 나타낸다.                        0  실행이 정상 종료                        1403  NOT FOUND                         음수  프로그램 또는 시스템 장애     *sqlca.sqlerrm.sqlerrml sqlca.sqlerrm.sqlerrmc의 텍스트의 길이  *sqlca.sqlerrm.sqlerrmc 가변 길이의 문자열이고, sqlca.sqlcode 내에                                              표시된 에러번호에 대응하는 에러메세지  *sqlca.sqlerrd   4바이트 2진 정수 배열 ORACLE RDBMS의 내부상황을                                파악하기 위해 사용. sqlca.sqlerrd[2]는 INSERT나 UPDATE                               처럼 DML 처리에 대해서 몇 개의 행이 처리 됐는지를 나타냄  *sqlca.sqlwarn   프리컴파일 중에 발생한 여러가지 상황에 대한 경고        sqlca.sqlwarn[0]  "W"가 설정된 경우 1개 이상의 경고가 설정되어 있음

5.3 WHENEVER 문

  에러를 검출할 때 어떤 처리를 취해야 할 지를 결정한다.   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             지정한 라벨이 붙은 문으로 제어를 옮긴다.

6. 동적 정의문

6.1 동적 정의문의 정의

동적 정의문이란, 컴파일시에 정의되지 않는 SQL 문이다. 다시 말해서, 동적 정의문은 각각의 실행 때마다 변경이 가능하고, 실제로 많은 경우에 변경된다.

6.2 동적 정의문의 종류

방법 1 : EXECUTE IMMEDIATE 문의 사용  모든 SQL 문(SELECT 문 제외)을 프리컴파일해서 이것을 실행한다.  SQL 문은 상수 또는 호스트 변수 중 어느 것이라도 상관없다.  SQL 문에는 호스트 변수를 포함하지 않는다.방법 2 : PREPARE 문 및 EXECUTE 문의 사용  모든 SQL 문(SELECT 문 제외)을 받아들여 이것을 수행한다.  SQL 문 중에 호스트 변수를 포함할 수 있다.  방법 3 : PREPARE 문 및 FETCH 문의 사용  선택을 행할 수 있다. SQL 문 중에 호스트 변수를 포함할 수 있다.  이 방법은 PREPARE, DECLARE, OPEN, FETCH의 순서로 행한다.방법 4 : 바인드 및 정의 기술자의 사용  1행의 SELECT 및 여러 행의 SELECT를 포함하는 모든 SQL 문을  사용할 수 있다.

6.3 EXECUTE IMMEDIATE 의 사용

/* 예제 #10 */#include /***************************************************************This is is a sample Pro*C program which will prompt for aWHERE clause to be used in an update statement. This is to beused with EXECUTE IMMEDIATE.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[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, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR STOP;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    strcpy(select, "UPDATE EMP SET COMM = 100 WHERE");    printf("Please enter where clause for the following : \n");    printf("%s", select);    scode = scanf("%s", where);    if(scode == EOF !! scode == 0)    {        printf("Invalid entry. \n");        exit(1);    }    strcat(select, where);    EXEC SQL EXECUTE IMMEDIATE :select;    printf("%d records updated. \n", sqlca.sqlerrd[2]);    EXEC SQL WHENEVER SQLERROR CONTINUE;    EXEC SQL COMMIT WORK RELEASE;    exit(0);}

6.4 PREPARE 및 EXECUTE 의 사용

/* 예제 #11 */#include /***************************************************************This is is a sample Pro*C program which will prompt for aWHERE clause to be used in an update statement. This is to beused with PREPARE and EXECUTE.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    float comm;    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, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR GOTO errrpt;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    strcpy(select, "UPDATE EMP SET COMM = :comm WHERE");    printf("Please enter where clause for the follwing : \n");    printf("%s", select);    scode = scanf("%s", where);    if(scode == EOF !! scode == 0)    {        printf("Invalid entry. \n");        exit(1);    }    strcat(select, where);    EXEC SQL PREPARE S1 FROM :select;    printf("Please enter commission : ");    scanf("%f", &comm);    EXEC SQL EXECUTE S1 USING :comm;    printf("%d records updated. \n", sqlca.sqlerrd[2]);    EXEC SQL WHENEVER SQLERROR CONTINUE;    EXEC SQL COMMIT WORK RELEASE;    exit(0);errrpt:    printf("\n %70s \n", sqlca.sqlerrm.sqlerrmc);    EXEC SQL ROLLBACK WORK RELEASE;    exit(1);}        

6.5 PREPARE, DECLARE, OPEN, FETCH, CLOSE 의 사용

/* 예제 #12 */#include /***************************************************************This is is a sample Pro*C program which will prompt for aWHERE clause to be used in a select statement.This sample uses PREPARE, DECLARE, OPEN, FETCH, CLOSEsince this may be a multi-row select and world require a cursor.***************************************************************/EXEC SQL BEGIN DECLARE SECTION;    VARCHAR uid[20];    VARCHAR pwd[20];    int deptno;    float sal;    char select[132];EXEC SQL END DECLARE SECTION;EXEC SQL INCLUDE SQLCA;void main(void){    char where[80];    int i, scode;    /* log into ORACLE */    strcpy(uid.arr, "SCOTT");                       /* copy the user name */    uid.len = strlen(uid.arr);    strcpy(pwd.arr, "TIGER");                       /* copy the password */    pwd.len = strlen(pwd.arr);    EXEC SQL WHENEVER SQLERROR GOTO errrpt;    EXEC SQL CONNECT :uid IDENTIFIED BY :pwd;    printf("Connected to ORACLE user : %s\n", uid.arr);    strcpy(select, "SELECT ENAME, SAL FROM EMP ");    printf("Please enter where clause for the following : \n");    printf("%s", select);    scode = scanf("%s", where);    if(scode == EOF !! scode == 0)    {        printf("Invalid entry. \n");        exit(1);    }    strcat(select, where);    EXEC SQL PREPARE S1 FROM :select;    EXEC SQL DECLARE C1 CURSOR FOR S1;    EXEC SQL OPEN C1;    printf("Employee       \tSalary       \n");    printf("--------------\t-----------\n");    EXEC SQL WHENEVER NOT FOUND GOTO endloop;    for(i = 0; ; i++)    {        EXEC SQL FETCH C1 INTO :ename, :sal;      printf("%10s\t%6.2f\n", ename, sal);    }endloop:    printf("\n\n%d records selected.\n", i);    EXEC SQL WHENEVER SQLERROR CONTINUE;    EXEC SQL COMMIT WORK RELEASE;    exit(0);errrpt:    printf("\n %70s \n", sqlca.sqlerrm.sqlerrmc);    EXEC SQL ROLLBACK WORK RELEASE;    exit(1);}

7.1 STORED PROCEDURE 의 사용

/* calldemo.sql */rem Rem    calldemo.sql - Rem    DESCRIPTIONRem    Rem    RETURNSRem CREATE OR REPLACE PACKAGE calldemo AS   TYPE name_array IS TABLE OF emp.ename%type       INDEX BY BINARY_INTEGER;   TYPE job_array IS TABLE OF emp.job%type       INDEX BY BINARY_INTEGER;   TYPE sal_array IS TABLE OF emp.sal%type       INDEX BY BINARY_INTEGER;   PROCEDURE get_employees(     dept_number IN     number,    -- department to query     batch_size  IN     INTEGER,   -- rows at a time     found       IN OUT INTEGER,   -- rows actually returned     done_fetch  OUT    INTEGER,   -- all done flag     emp_name    OUT    name_array,     job         OUT    job_array,     sal         OUT    sal_array);END calldemo;/CREATE OR REPLACE PACKAGE BODY calldemo AS   CURSOR get_emp (dept_number IN number) IS       SELECT ename, job, sal FROM emp           WHERE deptno = dept_number;   PROCEDURE get_employees(     dept_number IN     number,     batch_size  IN     INTEGER,     found       IN OUT INTEGER,     done_fetch  OUT    INTEGER,     emp_name    OUT    name_array,     job         OUT    job_array,     sal         OUT    sal_array) IS   BEGIN       IF NOT get_emp%ISOPEN THEN      -- open the cursor if           OPEN get_emp(dept_number);  -- not already open       END IF;       done_fetch := 0;  -- set the done flag FALSE       found := 0;       FOR i IN 1..batch_size LOOP           FETCH get_emp INTO emp_name(i), job(i), sal(i);           IF get_emp%NOTFOUND THEN    -- if no row was found               CLOSE get_emp;               done_fetch := 1;   -- indicate all done               EXIT;           ELSE               found := found + 1;  -- count row           END IF;       END LOOP;   END;END;/ /* 예제 #13 */#include #include /***************************************************************This program connects to ORACLE using the SCOTT/TIGER account.  The program declares several host arrays, then calls a PL/SQL stored procedure (GET_EMPLOYEES in the CALLDEMO package) that fills the table OUT parameters. The PL/SQL procedure returns up to ASIZE values.****************************************************************/EXEC SQL INCLUDE sqlca.h;typedef char asciz[20];typedef char vc2_arr[11];EXEC SQL BEGIN DECLARE SECTION;    /* User-defined type for null-terminated strings */    EXEC SQL TYPE asciz IS STRING(20) REFERENCE;    /* User-defined type for a VARCHAR array element. */    EXEC SQL TYPE vc2_arr IS VARCHAR2(11) REFERENCE;    asciz     username;    asciz     password;    int       dept_no;                  /* which department to query? */    vc2_arr   emp_name[10];            /* array of returned names */    vc2_arr   job[10];    float     salary[10];    int       done_flag;    int       array_size;    int       num_ret;                 /* number of rows returned */EXEC SQL END DECLARE SECTION;long      SQLCODE;void print_rows();            /* produces program output      */void sql_error();             /* handles unrecoverable errors */main(){    int   i;    char  temp_buf[32];    /* Connect to ORACLE. */    EXEC SQL WHENEVER SQLERROR DO sql_error();    strcpy(username, "scott");    strcpy(password, "tiger");    EXEC SQL CONNECT :username IDENTIFIED BY :password;    printf("\nConnected to ORACLE as user: %s\n\n", username);    printf("Enter department number: ");    gets(temp_buf);    dept_no = atoi(temp_buf);    /* Print column headers. */    printf("\n\n");    printf("%-10.10s%-10.10s%s\n", "Employee", "Job", "Salary");    printf("%-10.10s%-10.10s%s\n", "--------", "---", "------");    /* Set the array size. */    array_size = 10;    done_flag = 0;    num_ret = 0;    /*  Array fetch loop.     *  The loop continues until the OUT parameter done_flag is set.     *  Pass in the department number, and the array size--     *  get names, jobs, and salaries back. */     for ( ; ; )    {        EXEC SQL EXECUTE             BEGIN calldemo.get_employees                (:dept_no, :array_size, :num_ret, :done_flag,                 :emp_name, :job, :salary);            END;        END-EXEC;        print_rows(num_ret);        if(done_flag) break;    }    /* Disconnect from the database. */    EXEC SQL COMMIT WORK RELEASE;    exit(0);}void print_rows(int n){    int i;    if (n == 0)    {        printf("No rows retrieved.\n");        return;    }    for (i = 0; i < n; i++)        printf("%10.10s%10.10s%6.2f\n", emp_name[i ], job[i ], salary[i ]);} /* Handle errors. Exit on any error. */void sql_error(){    char msg[512];    int buf_len, msg_len;    EXEC SQL WHENEVER SQLERROR CONTINUE;    buf_len = sizeof(msg);    sqlglm(msg, &buf_len, &msg_len);    printf("\nORACLE error detected:");    printf("\n%.*s \n", msg_len, msg);    EXEC SQL ROLLBACK WORK RELEASE;    exit(1);}

8. Pro*C/C++의 사용

8.1 디렉토리 또는 경로의 설정

OS에서 디렉토리 또는 경로를 사용하고 있는 경우 경로 또는 디렉토리의 이름이 장치의 지정과 함께 올바른 지를 확인해야 한다.

8.2 커맨드 구문

일반적인 커맨드 구문은 다음과 같다.

PCC INAME = filename {option=value (option=value …)}

8.2.1 필수 인수

필수 인수는 "INAME = 파일명" 하나뿐이다. 파일의 확장자나 파일타입을 지정하지 않는 경우 "HOST = 언어"를 인수로서 지정해야 한다.

Pro*C에서 입력파일 및 출력파일에 대한 파일타입 및 확장자의 디폴트값은 다음과 같다.

OS          입력파일타입 또는 확장자      출력파일타입 또는 확장자━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━VAX/VMS               .pc                                  .cIBM/VM/CMS         csql                                cUNIX                      .pc                                  .c

8.2.2. Pro*C의 실행시 옵션

  실행시에는 복수의 옵션을 사용할 수 있다.OPTION = value · AREASIZE · ASACC · ERRORS · HOLD_CURSOR/RELEASE_CURSOR · HOST · INCLUDE · IRECLEN · LNAME · LRECLEN · LTYPE · MAXLITERAL · MAXOPENCURSOR · ONAME · ORACA · ORECLEN · PAGELEN · REBIND · SELECT_ERROR · USERID · XREF

'ORACLE' 카테고리의 다른 글

MS-SQL 접속 삽질의 날!!!  (0) 2007.06.29
CORE DUMP 해결방법  (0) 2007.03.06
sqlplus 사용을 고급화하기.  (0) 2007.01.12
오라클 Role 관리  (0) 2006.12.18
테이블의 필드명 변경하기...  (0) 2006.12.15