2010년 9월 29일 수요일

Excel 2010 2개 이상 열때 새창으로 생성하기

 MS Office 2010 기준

 

 시작 > 실행 > regedit

 

HKey_Classes_Root\Excel.Sheet.8\Shell\Open
HKey_Classes_Root\Excel.Sheet.12\Shell\Open

 

위 두 경로를 오른클릭 > 내보내기  로 백업 권장

 

 위의 두 경로에서 ddeexec 디렉토리 삭제

     HKey_Classes_Root\Excel.Sheet.8\Shell\Open\command

     HKey_Classes_Root\Excel.Sheet.12\Shell\Open\command

 

 

 

 command 디렉토리에서 기본값(REG_SZ)를 아래로 변경

 "C:\Program Files\Microsoft Office\Office14\EXCEL.EXE" /m "%1"

 

 기본값(REG_SZ)를 제외한 다른 키 값 삭제

 

 Excel 실행시켜 확인

2010년 8월 24일 화요일

주식워런트증권(ELW)

- 어떤 종목을 미래에 정한 어느시점에 미리 정한 가격으로 사거나 팔 수 있는 권리로

  일반증권과 같이 매매 할 수 있게 한 유가증권

  만기전에도 ELW의 가치에 따라 얼마든지 사거나 팔수 있다

EX) 삼성전자 현재가 600,000 / 행가가 650,000  / 만기일 3개월뒤 / 만기가 700,000

=> 삼성전자 현물에 투자하지 않고 주식워런트에 투자하면 3개월뒤 70만원으로 상승한

   삼성전자 주식을 행사가인 65만원에 살수있는 권리가 주어진다

 


- 주식워런트의 장점

 


  1. 일반주식계좌에서 쉽게 할 수 있다

  2. 기초자산에 투자하는것보다 고수익이 난다

  3. 상승장에서는 만기를 노려 안전하게 투자할 수 있다

  4. 하락장에서도 수익을 낼 수 있다

  5. 변동성장에서는 양방향 투자도 할 수 있다 -> 단기투자로 안전하게

  6. 기초자산이 대형주라 세력의 개입이 없고 방향성 판단이 쉬운편이다

  7. 적은금액으로도 투자할 수 있다

  8. 헷지전략으로 이용할 수 있다 (보험의 성격)

  9. 거래세가 없다(수수료가 싼 증권사가 유리)

  

- 주의할점

  1. 고수익인만큼 고위험이 뒤따른다 (장점이자 단점이다)

  2. 전체적인 시황을 고려하면서 업종/종목의 방향성 판단이 아주 중요하다

  3. 만기일,손익분기점,행사가격,레버리지 등을 잘 따져야 한다

 


- 기본용어

 *기초자산 - ELW의 기초가 되는 KOSPI200지수나 KOSPI200에 71개 대형주

 * 만기일(잔존일) - 기초자산의 만기평가금액이 결정되는 최종거래일까지 남은 일수

                   시간가치의 중요성 (가능성)

 * 행사가격 - 권리행사의 기준이 되는 가격

              현재가와의 차이가 중요 (가능성)

 * 레버리지 - 기초자산 변화율 , 가격움직임(1%)에 따른 ELW의 변화비율

              기어링 * 델타 = 레버리지   /  지렛데효과

 * 프리미엄  - 손익분기점 = 행사가 +( ELW가격 / 전환비율)

               손익분기율 = (손익분기점 - 현재가) / 현재가

 * 기어링  - 기초자산에 투자하는것이 ELW에 투자하였을 때 보다 몇배의 비용을 수반하는지

                 보여주는 지표 

             기어링 = 기초자산의 가격 / (ELW/전환비율)  -> 11.81배

 


 * 델타 - 기초자산이 1원 움직일때 ELW의 가격변화

          EX) ELW의 가격변화 = (델타*기초자산의 가격변화)*전환비율  

    -> 삼성전자 (전환비율 0.02) /델타 0.4712) 10,000상승시 ELW 94.72원상승

 


 *전환비율 -  권리행사를 하기위해 필요한 ELW의 수 ( 1/전환비율)

              1권리 :  ELW비율

 * 세타 - 1일이 지남으로인한 시간가치 하락분

 * 패리티 - 기초자산현재가 / 행사가

 * 괴리율 - ELW이론가와 현재가와의 차이율

            (ELW현재가 = ELW이론가+(이론가*괴리율)

 


- 만기일과 결제사항

   * 최종거래일 - ELW를 거래할 수 있는 마지막 날

   * 만기일 - ELW의 권리행사자가 확정되는 날

   * 만기지급일 - 현금결제가 일어나서 증권계좌에 현금이 입금되는 날

 


- 만기평가가격 산술 방법

   * 기초자산 - 최종거래일을 포함 직전 5일간 종가의 평균값

   * 주가지수 - 최종거래일의 종가를 만기평가지수로 사용

 


- 발행인

  발행증권사마다 다 다르지만 현재는 많이 안정화 평준화 됬으며 ELW 종목의 가치나       

  인기에 따라 유동성의 차이가 나기도 한다

  1. 유동성풍부

     LP(유동성공급자)의 중요성 - 안정적이고 적절한 호가 제시

  2. 적정한 호가 스프레드(Bid-A나 Spreads)

     매도가와 매수가의 차이는 어느 거래소에서든지 존재하는 거래비용의 일부분이다

     차이가 작을수록 투자자에게 유리함

     호가스프레드는 거래량이 클수록 작고 작을수록 크다

  

- 좋은 ELW 고르는 법

   1. 올바른 기초자산 선정

      방향 : 강세장(상승장) -콜워런트 / 하락장(약세장) - 풋워런트

      타이밍 : 단기 외가격워런트 - 공격적투자자 / 장기 내가격워런트 - 보수적투자자

      변동폭 : 외가격ELW - 기초자산이 단기간에 급격히 움직일때 적합

               내가격ELW - 가장보수적이며 기초자산의 장기적 움직임이 예상될때 적합

   2. 만기 90~120일 남음것  - 길면 둔하고 짧으면 급변함

      레버리지 4~6  / 거래량이 많거나 LP가 적정호가를 제시하는 ELW

2010년 8월 17일 화요일

2010년 8월 4일 수요일

Argument 있는 Retrieve의 조회후 dw의 쿼리 보기

 

보통 실행되는 sql을 미리보려면

sqlpreview event 의 sqlsyntax 나 GetSqlSelect() 함수를 이용하는데

이때 Argument 값은 :argument 형식으로 보여지게 되어

실제 어떤 값이 적용 됐는지 알기 힘든경우가 있습니다.

 

Debug를 돌리다보면 Argument 값에 실제 값을 볼수 있는데 Debug가

프로그램 실행시에 봐야 하는경우도 있겠지요.

 

방법은 이렇습니다.

우선 DBprofile 에서 Edit 를 누르시면 생성한 DBprofile의 여러가지 설정을

하시는 화면이 뜨는데요.

1. DBprofile 에서 Edit 선택.

2. Tansaction 탭을 선택.

3. Disable Bind 체크.

4. Prieview 탭선택

5. Prieview 내용중 SQLCA.DBParm = "DisableBind=1" 부분을 복사

6. Application 이나 기타 DB연결 정보 적으신곳에 붙여 넣습니다.

ORACLE은 이렇고요

 

MS-SQL의 경우 Disable Bind 체크를 해도 SQLCA.DBParm 이부분에 DisableBind=1 이 나타나지 않습니다.

거꾸로 체크를 하지 않으면 DisableBind = 0 이라고 나타나지요...

MS-SQL은 DisableBind=1 이부분을 복사하지 않으셔도 체크만 하시면 됩니다.

(ADO.NET의 경우만 확인했습니다. ODBC나 OLE는 확인 하지 못했습니다.)

 

ORACLE은 DBprofile 설정시 Disable Bind 가 기본적으로 체크되어 있지 않은것 같구요

MS-SQL은 기본적으로 체크가 되어있는거 같습니다. 

(이부분은 따로 확인해보진 않았지만 DisableBind 부분을 건드린 기억이 없기에 말씀 드린것입니다.)

 

보태기 :

만약 저 내용을(Argument에 실제로 들어간 값을) GetItem....()으로 구해 와야 하는경우가 있다면

select col_1

,        col_2

,        :argument_1 /*compute column으로 생성*/

from   table_1

where pk_01 =  :argument_1

과 같은 식으로 하시면

,        :argument_1 /*compute column으로 생성*/ 

부분이 dwo 상에 compute column으로 생성 됩니다.


ex ) 스크립트 (dw.sqlpreview 이벤트)

if keydown(keyshift!) and keydown(keycontrol!) then
 FileOpen('.\temp_sql_' + this.classname() + '.txt',StreamMode!,Write!,LockWrite!,Replace!)
 long  ll_i
 
 FileWrite(1, '/*########## ' + this.classname() + ' = "' + this.dataobject + '" ##########*/~r~n~r~n~r~n')
 
 for ll_i = 1 to len(sqlsyntax) step 32765
  FileWrite(1, mid(sqlsyntax, ll_i, 32765))
 next
 FileClose(1)
 Run("notepad .\temp_sql_" + this.classname() + ".txt")
end if

 

/*

이 문장을 Datawindow 의  sqlpreview 이벤트에 넣어서 사용하고 있습니다.

dw는 유저오브젝트를 사용하는 경우가 많을 건데... 거기다 넣으면 훨씬 좋겠지요.

시프트키와 콘트롤키를 누르고 조회를 하면 실행되는 dw의 sql명령이 아규먼트의 값도 치환되어서

노트패드로 뜨기때문에 오류 검색을 쉽게 할 수 있습니다.

일반적으로 조회할때는 안 뜨고... 개발자가 필요할때만 SQL문장을 확인 할 수 있는 거죠..  */

2010년 7월 28일 수요일

기본 명령어

1. 배열(Array)처리 함수
LowerBound : 지정한 배열의 하위 경계
UpperBound : 지정한 배열의 상위 경계


2. Bolb관련 함수
Blob : 텍스트 데이터를 Blob 데이터로 변환 또는 복사
BlobEdit : PB가 지원하는 데이터를 Blob변수로 복사
BlobMid : Blob 데이터 문자열에서 N번째 문자를 반환
Len : 문자열의 길이


3. 데이터형 검사 및 변환 함수
Char : blob,정수,문자열을 문자로 바꿔서 반환
Dec : 문자열의 내용을 십진수로 바꿔서 반환
Double : 문자열의 내용을 Double로 바꿔서 반환
Integer : 문자열의 내용을 정수로 바꿔서 반환
Long : 문자열의 내용을 long으로 바꿔서 반환
Real : 문자열의 내용을 실수로 바꿔서 반환
Date : 데이터베이스로부터 읽은 DateTime값에서 Date부분만 빼온다.
DateTime : Date나 Time을 DateTime 값으로 변환한다.
IsDate : 지정한 문자열이 유효한 Date값을 지녔는지 검사한다.
IsNull : 넘어온 인자가 NULL인지 검사한다.
IsNumber : 지정한 문자열이 숫자값을 지녔는지 검사한다.
IsTime : 지정한 문자열이 유효한 Time값을 지녔는지 검사한다.
String : 지정한 형식으로 문자열을 얻는다.
Time : 데이터베이스로부터 읽은 DateTime값에서 Time부분만 빼온다.


4. 날짜,요일,시간 처리 함수
Day : 일자를 구한다(1에서 31 사이의 정수)
DayName : 주간의 요일명을 구한다.
DayNumber : 주간의 요일을 숫자로 표현한다.(예를들면 일요일은1, 목요일은 5)
DaysAfter : 지정한 날짜에 n일전,후를 구한다.
Hour : 주어진 시간의 시 값을 구한다.
Minute : 주어진 시간의 분 값을 구한다.
Month : 주어진 날짜의 월 값을 구한다.(1에서 12까지)
Now : 클라이언트의 시스템 시간을 구한다.
RelativeDate:주어진 날짜를 기준으로 n일 후 날짜를 구한다.
RelativeTime:주어진 시간을 기준으로 n초 후 시간을 구한다.
Second : 주어진 시간의 초 값을 구한다.
Today : 클라이언트의 현재 날짜를 구한다.
Year : 주어진 날짜의 년 값을 구한다.(1000에서 3000년까지임)


5.DDE클라이언트 함수
CloseChannel:OpenChannel함수로 열린 DDE서버 어플리케이션의 채널을 닫는다.
ExecRemote : 서버 어플리케이션에게 명령 실행을 요구한다.
GetDataDDE : 연결된 서버 어플리케이션으로부터 새로운 데이터를 받아온다.
GetDataDDEOrigin:연결된 서버 어플리케이션으로부터 원래의 데이터를 받아온다.
GetRemote : 서버 어플리케이션에게 데이터를 요구한다.
OpenChannel: DDE서버 어플리케이션을 연다.
RespondRemote:서버에게 명령 또는 데이터가 클라이언트에게 받아들여졌는지를 알려준다.
SetRemote : 서버 어플리케이션에게 지정한 값을 설정하도록 한다.
StartHotLink:서버 어플리케이션과의 연결을 시작한다.
StopHotLink: 서버 어플리케이션과의 연결을 종료한다.


6. DDE서버 함수
GetCommandDDE: 클라이언트 어플리케이션이 보낸 명령을 구한다.
GetCommandDDEOrigin:어떤 클라이언트 어플리케이션이 명령을 보냈는지 구한다.
GetDataDDE : 클라이언트 어플리케이션이 보낸 데이터를 구한다.
GetDataDDEOrigin:어떤 클라이언트 어플리케이션이 데이터를 보냈는지 구한다.
RespondRemote:클라이언트에게 명령 또는 데이터가 서버에게 받아들여졌는지를 알려준다.
SetDataDDE : 클라이언트 어플리케이션에게 데이터를 보낸다.
StartServerDDE:파워빌더를 서버로 동작하게 한다.
StopServerDDE:파워빌더가 서버로 동작하는 것을 중지한다.


7. 파일처리 함수
FileClose : 파일 닫기
FileDelete : 파일 삭제
FileExists : 파일 존재 유/무
FileLength : 파일 길이
FileOpen : 파일 열기
FileRead : 파일 읽기
FileSeek : 파일 내 위치 이동
FileWrite : 파일에 쓰기
GetFileOpenName:파일 열기 공통 다이얼로그 열기
GetFileSaveName:파일 저장 공통 다이얼로그 열기


8. 라이브러리 함수
LibraryCreate:라이브러리 생성
LibraryDelete:라이브러리 삭제
LibrarDirectory:pb라이브러리 파일의 모든 오브젝트의 리스트를 구한다.
LibraryExport:라이브러리 파일의 모든 오브젝트를 Export한다.
Library Import:지정한 라이브러리 파일에서 오브젝트를 Import한다.


9.MAPI함수
mailAddress :메일 메세지에 주소를 주거나 주소 리스트를 보여준다.
mailDELETEMessage :메일 메시지를 지운다.
mailGetMessages :메지시 id를 얻어온다.
mailHandle :내부 메일 시스템 핸들을 얻어온다.
mailLogOff :메세징 시스템과의 세션을 끊는다.
mailLogOn :메세징 시스템과의 세션을 시작한다.
mailReadMessage :메일 메시지를 읽는다.
mailRecipientDetails:지정된 수취인의 주소 정보를 보여준다.
mailResolveRecipient:불분명한 수취인 명을 결정한다.
mailSaveMessage :사용자 수신함에 새로운 메시지를 생성하거나 기존에 있는 메시지를 대체한다.
mailSend :메일 메시지를 보낸다.


10. 수치 처리 함수
Abs : 수치의 절대값을 얻는다.
Ceiling : 지정한 수보다 크거나 같은 최소 정수를 구한다.
Cos : 주어진 각도의 코사인 값을 구한다.
Exp : e를 Number만큼 거듭제곱한 값을 구한다.(e=2.71828182845904)
Fact : 계승값을 구한다. Number의 계승값은 1*2*3*...* Number이다.
Int : 소수점 이하를 버리고 가장 가까운 정수로 변환한다.
Log : 지정 숫자의 자연로그값을 구한다.
LogTen : 지정한 숫자에 대해 밑이 10인 로그값을 구한다.
Max : 두 수 중 큰 수를 구한다.
Min : 두 수 중 작은 수를 구한다.
Mod : 두 수를 나눈 나머지를 구한다.
Pi : 3.14159265358979를 구한다.
Rand : 난수를 구한다.
Randomize : 난수 발생기를 초기화한다.
Round : 숫자를 지정한 자릿수로 반올림한다.
Sign : 숫자의 부호를 결정한다. Number가 양수이면 1을 표시해주고 0이면 0,
음수이면 -1을 표시한다.
Sin : 주어진 각도의 사인 값을 구한다.
Sqrt : 양의 제곱근을 구한다.
Tan : 주어진 각도의 탄젠트 값을 구한다.
Truncate : 숫자의 소수점 이하를 버리고 정수로 변환한다.


11. 출력(Print)함수
Print : 현재 글꼴로 문자열을 인쇄한다.
PrintBitmap: 지정한 인쇄공간에 비트맵 이미지를 인쇄한다.
PrintCancel: 인쇄를 취소한다.
PrintClose : 현재 페이지를 프린터에 보내고 인쇄를 멈춘다.
PrintDefineFont:인쇄작업시 폰트를 정의한다. 파워빌더는 각각의 인쇄 작업에 대해 8가지 폰트를 제공한다.
PrintLine : 지정한 위치에 지정한 굵기로 타원을 그린다.
PrintOpen : 현재 페이지를 프린터에 보내고 새로운 페이지를 셋한다.
PrintOval : 지정한 위치에 지정한 굵기로 타원을 그린다.
PrintPage : 지정한 위치에 지정한 굵기로 둥근 모서리의 사각형을 그린다.
PrintRect : 지정한 위치에 지정한 굵기로 사각형을 그린다.
PrintRouneRect:지정한 위치에 지정한 굵기로 둥근 모서리의 사각형을 그린다.
PrintSend :지정한 문자열을 프린터에게 보낸다.
PrintSetFont:현재 인쇄 작업에 대한 글꼴을 지정한다.
PrintSetSpacing:라인간 너비를 지정한다.
PrintSetup : 프린터 설정 다이얼로그 박스를 부른다.
PrintText : 지정한 위치에 지정한 문자를 인쇄한다.
PrintWidth : 현재 글꼴에서 지정된 문자열의 너비를 구한다.
PrintX : 커서의 X좌표를 구한다.
PtintY : 커서의 Y좌표를 구한다.


12. 문자열 처리 함수
Asc : 문자열의 첫번째 문자의 ASCII값을 구한다.
Char : 주어진 ASCII값에 해당하는 문자를 구한다.
Fill : 지정한 문자를 반복시켜서 문자열을 만든다.
Left : 문자열의 시작부터 지정한 수의 문자를 읽어온다.
LeftTrim : 문자열의 시작에 있는 공백을 없앤다.
Len : 문자열의 길이를 구한다.
Lower : 주어진 문자열 내의 대문자를 소문자로 고친다.
Mid : 주어진 문자열에서 시작 위치와 끝 위치를 지정해 문자열의 일정 부분만을 구한다.
Pos : 다른 문자열에서 주어진 문자열의 위치를 찾는다.
Replace : 문자열의 일부를 다른 문자열로 바꾼다.
Right : 문자열의 끝에서 주어진 수의 문자를 얻어온다.
RightTrim : 문자열의 끝에 있는 공백을 없앤다.
Space : 지정한 길이로 공백 문자열을 얻는다.
Trim : 문자열의 시작과 끝의 공백을 없앤다.
Upper : 지정한 문자열 내의 소문자를 대문자로 고친다.


13. 시스템 및 환경 함수(System and Environment)
Clipboard : 윈도우의 클립보드의 내용을 얻는다.
GetApplication:현재 어플리케이션의 핸들을 구한다.
CommandParm: 어플리케이션 실행시 지정된 파라미터가 있을 경우 그값을 구한다.
DoScript : 애플 스크립트(AppleScript)를 실행한다.(매킨토시 버전에만 해당)
GetEnvironment:시스템의 운영체제와 프로세서 등과 같은 정보를 얻는다.
Handle : Window SDK함수를 부르기 위해 사용한다.
Post : 지정한 윈도우에 대한 메시지를 메시지 큐에 마지막에 삽입한다.
ProfileInt : 지정한 프로파일에서 숫자값을 얻어온다.
ProgileString:지정한 프로파일에서 문자열을 얻어온다.
Restart : 모든 스크립트의 실행을 중지하고, 모든 윈도우를 닫으며 데이터베이스에 Commit한후 연결을 끊고 다시 어플리케이션을 실행시킨다.
Run : 지정한 어플리케이션을 실행시킨다.
Send : 지정한 윈도우에 메시지를 순차적으로 보낸다.
SetProfileString:지정한 프로파일 값을 저장한다.
ShowHelp : 윈도우 3.x에 있는 도움말(Help)파일을 읽어 파워빌더 어플리케이션에서 사용할 수 있다.
SignalError: 어플리케이션 레벨에서의 시스템 에러를 발생한다.
Yield : 반복문 안에서 다른 오브젝트나 어플리케이션의 메시지가 발생됐는지를 체크할수 있게 한다.


14. 시간처리 함수
CPU : 현재 실행중인 PB어플리케이션 프로그램의 시작 시간부터 현재까지의 CPU시간을 구해준다.
Idle : 사용자가 아무런 입력이 없이 지정한 시간이 흐르면 Idle이벤트 발생시킨다.
Timer : 지정한 윈도우에 일정한 간격의 타이머를 지정하여 Timer이벤트를 발생시킨다.


15. 그밖의 함수
Beep : 정해진 시간(초단위)동안 경고음을 발생한다.
DBHandle : DBMS의 핸들을 반환한다.
IsValid : 지정한 윈도우가 열려있는지 검사한다.
KeyDown : 사용자가 특정한 키를 눌렀는가 검사한다.
MessageBox : 메시지 박스를 출력한다.
PixelsToUnits: 픽셀(Pixel)을 PB의 Unit로 바꾼다.
RGB : 특정 색상을 표현하는 Long형 값을 반환한다.
SetNull : 변수의 유형에 상관없이 변수를 Null로 지정한다.
SetPointer : 마우스 포인터를 지정한 모양으로 바꾼다.
TypeOf : 오브젝트의 형을 결정한다. 예를들면 CheckBox, Picture, RadioButton 등이다.
UnitsToPixels: PB의 Unit를 픽셀(Pixel)로 바꾼다.


1. UpperBound(배열명,{배열차원}) : 가끔 사용
(1) 개념 : 배열의 가장높은 경계값을 알아낸다.
Option으로 배열의 차원을 지정할 수 있으며 Default 차원은 1차원이다.

(2) Return : integer(배열의 가장높은 경계값)

(3) 예제
가)
integer li_number[7] , li_return
li_return = UpperBound(li_number) // li_return 은 7이 된다.
나)
string ls_name[5,6] integer li_return
li_return = UpperBound(ls_name,1) // li_return 은 5가 된다
li_return = UpperBound(ls_name,2) // li_return 은 6이 된다

(4) 메모 : 가변길이 선언 배열에서 ( ls_text[] )
위의 함수를 사용하여 0이 Return되면 배열이 아직 현 메모리에 적재되지 않았음을 의미한다.

(5) 상대함수 : LowerBound()


2. IsDate(string) : 자주 사용
(1) 개념 : 특정한 String이 정확한 Date인지를 확인한다.

(2) Return : Boolean ( Date가 맞으면 True 아니면 False이다. )

(3) 예제 boolean lb_check
lb_check = IsDate("1996/05/22") // lb_check 는 True이다
lb_check = IsDate("1996/00/22") // lb_check 는 False 이다

(4) 메모 : 특정한 String등을 Date로 변환시키기 직전에 많이 사용한다.

(5) 유사함수 : Isnull() , Isnumber() , Istime() , Isvalid()


3. Date(datetime) , : 자주사용 Date(string) , Date(year,month,day)
(1) 개념 : datetime , string , 년월일의 integer값을 Date 변수타입으로 변환한다

(2) Return : Date ( Valid 한 Date가 아닐때는 1900-01-01을 Return한다 )

(3) 예제 datetime ldt_this date ld_new
ld_new = Date(ldt_this)
IF ld_new = Date("1900-01-01") THEN
Messagebox("ERROR",'정확한 일자가 아닙니다 !!')
return
END IF
ld_new = Date("1996/08/15") ld_new = Date(1999,11,23)

(4) 유사함수 : DateTime()


4. Control명.ClassName() : 가끔사용 ClassName(변수명)
(1) 개념 : 특정한 Object의 Class명을 String으로 알아낸다.

(2) Return : String ( Error 발생시에는 empty string "" 이 반환된다)

(3) 예제
가)
string ls_name
ls_name = Parent.ClassName()
IF ls_name = "w_insa001u" THEN
sle_1.text = ls_name
END IF

// 어떤 Object의 Dragdrop Event 에서
string ls_name dragobject ldr_what
ldr_what = DraggedObject() ls_name = ldr_what.ClassName()
IF ls_name = 'em_delete' THEN
ldr_what.Drag(end!) Messagebox("Drag Object",'Drag된 Object 는 '& + ls_name + '입니다')
END IF

나)
long ll_qty string ls_class
ls_class = ClassName(ll_qty) // ls_class 는 'long' 을 받아온다
ls_class = ClassName(this) // ls_class 는 현 Object 의 Class 명칭을 받아온다


5. Object명.PostEvent(event명) : 자주사용
(1) 개념 : Script가 쓰여진 현 Event가 끝난뒤 특정 Object의 Event를 수행하게 한다. 위의 function은 script가 쓰여진 위치에 관계없음으로 그 이후에 어떤 scrip가 있다면 그것을 모두 수행한후에 실행된다.

(2) Return : Boolean (성공하면 true , event가 없거나 script가 없으면 false)

(3) 예제
cb_close.PostEvent(clicked!) // object에 기본적으로 있는 event일때
cb_close.PostEvent("ue_keydown") // User가 정의한 event일때


6. Object명.TriggerEvent(event명) : 매우 자주사용
(1) 개념 : 현 Event에서 어떤 특정Object의 특정Event를 즉각적 수행하고 돌아온다. Script가 쓰여진 위치가 중요하다

(2) Return : Boolean (성공하면 true , event가 없거나 script가 없으면 false)

(3) 예제
cb_check.TriggerEvent(clicked!) // object에 기본적으로 있는 event일때
cb_check.TriggerEvent("ue_check") // User가 정의한 event일때

(4) 메모 : 어떤 Event의 Script를 수행한다는 면에서는 Postevent와 Triggerevent는 동일하며 두 이벤트 중 어떤것을 써야할지의 선택기준은 현재의 Event가 수행되고 난뒤 어떤 Event를 이어서 수행시키느냐 (Postevent) , 즉각적으로 어떤 Event를 수행하느냐 (Triggerevent) 의 차이이다.

2010년 5월 26일 수요일

Delphi/C++Builder 2010 설치시 '' is not a valid integer value 에러

 

Delphi/C++Builder 2010 혹은 2009의 루트 폴더 설치 프로그램을 실행하면, 설치 프로그램의 초기 화면도 뜨기 전에 위의 첫번째 이미지와 같이 "'' is not a valid integer value"" 라는 에러가 나는 경우가 간혹 있습니다. 그런 후 '확인'을 누르면 위의 두번째 이미지처럼 Access Violation 에러가 다시 발생합니다.

이런 경우가 자주 발생하는 것도 아니고, 아주아주 드물게 한건씩 발생하는데요. 최근에 다시 이런 경우가 있어서 추적하다가 원인과 해결책을 알아냈습니다.

이것은, 설치하려는 PC에 이전에 설치했던 프로그램들 중 하나에서, CD의 AutoRun 기능을 동작하지 않도록 하기 위해 해당 프로그램의 개발자가 레지스트리의 AutoRun 항목을 아예 막아버리는 편법을 사용했기 때문입니다. (이런 어이없는 편법을 사용하는 개발자들이 꽤 되는 모양이더군요) 따라서 이런 문제가 발생할 때는, 레지스트리에서 해당 AutoRun을 막은 곳을 찾아 지워버리면 됩니다.

먼저, 레지스트리 에디터(regedit.exe)를 실행시키고, 아래의 키를 찾아갑니다.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion \IniFileMapping\Autorun.inf
위의 키가 존재하고, 그리고 그 (기본값)이 @SYS:DoesNotExist 이런 식으로 지정되어 있다면 이 케이스에 해당합니다.
 
Autorun.inf 키 자체를 삭제해버리시고, 윈도우를 재부팅하신 후, 다시 설치를 시도해보시면 잘 되실 겁니다. (원래 이 Autorun.inf 키가 존재하지 않는 것이 디폴트입니다)

2010. 4. 30 추가 -----------------------------------------------

간혹 이 레지스트리 키를 지웠는데도 계속 다시 이 키가 생기는 분이 있을 수 있습니다. 어떤 프로그램이 CD 자동실행 방지를 막기 위해 계속 이 레지스트리 키를 감시하다가 써넣고 있는 것으로 보이는데요. 아마도 그 범인은 안티바이러스 등의 보안 프로그램일 가능성이 높습니다. 이 레지스트리를 이용하는 방법을 공개한 사람의 목적이, USB 메모리를 감염시키는 바이러스를 막기 위한 간단한 방법으로서 소개했었기 때문입니다. 하지만 자동실행을 막는 표준적인 방법이 따로 있으며, 이 레지스트리 방법은 편법입니다.

이 레지스트리 키는 원래 없는 것이 디폴트인데도 다른 프로그램의 오동작까지 불러일으키면서도 계속 레지스트리 키를 만드는 것이므로 그 프로그램의 문제에 해당합니다. 게다가 이 레지스트리 키 방법이 자동실행을 막는 원칙적인 방법이 아닌 꽁수이기 때문에, 이 문제는 다른 CD/DVD 미디어의 루트 런처 프로그램들에서도 동일하게 발생할 수 있습니다.

하지만 어쨌든 결과적으로 Delphi나 C++Builder를 설치하려는 분에게는 문제가 되므로, 다른 해결책도 알려드리겠습니다.

위의 '' is not a valid integer value 에러 메시지는, 오직 DVD 미디어의 루트에 있는 설치 프로그램에서만 발생합니다. (2010 버전의 경우 install_RADStudio.exe, 2009 버전의 경우 install.exe) 이 설치 프로그램은 실제 Delphi/C++Builder를 설치하는 프로그램이 아니라 실제 설치 프로그램들을 실행해주는 런처 프로그램이구요.

하지만, 루트 폴더의 런처 프로그램이 아닌, 실제 설치 프로그램을 실행하시면 당연히 이런 문제가 발생하지 않습니다. Delphi/C++Builder 2010 및 2009 버전의 DVD 미디어에서 실제 설치 프로그램은 (드라이브):\Install\Setup.exe 입니다. 이것을 직접 실행시키면 위와 같은 에러 메시지가 발생하지 않고 정상적으로 설치가 됩니다.

2010년 5월 14일 금요일

코스피 200 <> 선물

1.  Backwardation (백워데이션)

역조시장(Inverted or Abnormal Market)에서 형성된 현물가격과 선물가격과의 차이를 말한다. 그러나,현물가격이 선물 가격보다 높은 이러한 백워데이션현장은 공급물량의 부족사태가 해 결되면 수요와 공급이 다시 균형상태를 찾게 되어 곧 베이시스 (basis)상태로 복귀하게 된다.

 

2. contango(컨탠고) & backwardation(백워데이션)


 
오늘은 "contango"와 "backwardation"에 대해 얘기해볼까 합니다.
프로그램매매를 이해하기 위해서는 contango, backwardation을 이해하셔야 합니다.

contango, backwardation 얘기를 하기 전에 우선 "basis"얘기 먼저 해야겠군요.

 

basis란 간단히 말하면 현물, 선물간의 가격차이를 말합니다.
주식시장에서 예를 찾자면, Kospi200현물가격과 Kospi200선물가격간의 차이를 바로 basis라고 할 수 있습니다.

즉,
현물가격 - 선물가격 = 보유비용 (현물보유수입 - 자금조달비용) = "basis"

 

상식적으로 생각할 때, 현물가격보다 선물가격이 더 비싼 것이 당연하지만, 현물의 매수가 폭발적으로 증가하거나 혹은 선물의 매도가 과도할 때 현물가격이 선물가격보다 비싼 가격역전이 발생할 수 있습니다.

여기서 선물가격이 현물가격보다 비쌀 때를 contango상태라고 하고, 현물가격이 선물가격보다 비쌀 때를 backwardation상태라고 합니다.


보통의 시장에서는 contango가 일반적이지만, 장중 일시적으로 현물가격이 선물가격을 역전하는 backwardation상태로 변하기도 합니다. 혹은 하루이상 backwardation상태가 이어지기도 하지요.

 

일반적인 상품선물시장에서는 현물의 물량부족 및 장래 수급상황의 전망 등에 따라 backwardation시장도 쉽게 볼 수 있지만, 금융선물시장에서는 contango 시장이 일반적이고 backwardation시장은 어디까지나 비정상시장(역조시장 : Inverted Market)이라고 하겠습니다.

 

basis는 현,선물 가격차이이므로 시간이 흐름에 따라 basis폭이 줄면서 결국 현물과 선물의 가격차이는 '0'에 가까와집니다. 즉, 현재의 선물가격이 만기일에 가서는 현물가격과 거의 일치하게 된다는 것입니다. 이를 basis convergence(수렴)이라고 합니다.

 

주가지수선물 9월물은 9일 만기를 맞아 basis가 수렴하여 선물의 생을 마감하고 더이상 선물이 아닌 현물로 남고 10일부터는 12월물이 최근월물이 되는 것이지요.

 

기관의 프로그램 매매가 basis수렴을 전제로 하여 이루어지고 또 이 프로그램 매매가 주가에 상당한 영향력을 행사하고 있기 때문에 basis수렴을 이해하는 것이 그만큼 중요하다 하겠습니다.

2010년 3월 15일 월요일

ELW로 깡통 된 계좌

감정 통제를 실패한 자료

 

철저하게 다시 감정을 통제 하고 냉정하게 판단을 해야 한다.

ELW 관련 매매

1. 정확히 목표를 설정 해라!

    이익 매도할 가격과 손절 라인을 절대적으로 지켜라

    손절은 곳 이익과 이익 매도는 자신의 앞으로 일어날 이익과 직결되며

    매도 한 금액보다 현 금액이 올랐다고 해서 후회하거나

    재매매로 이익을 볼생각은 금물이다.

 

2. ELW는 파생으로 매우 위험한 분류에 속하니

    투자 자산의 10% 이하로만 투자 하여하 하며

    가장 좋은 방법은 잃어도 후회 없는 금액으로 하는 것이 가장 이상적인 투자 금액이다.

 

3. ELW의 세력은 분명히 존재한다.

    ELW의 세력은 큰개미가 될수 있거나 LP회원사가 될수 있다.

    LP회원사는 개인보다 더 빠른 시스템을 쓰고 있어서 절대로 같은 시점을 내다보거나 하면

    1000% 개미의 패배이다.

    LP회원사보다 좀더 빠른 시점 예측 좀더 빠른 계산을 하는 것은 필수적이다.

 

4. 항상 냉정해라.

    항상 냉정하고 침착해야 하면 손 떨림이 없어야 한다.

    이익이 발생 하였다고 해서 흥분해서 매도 하거나

    손실이 생겼다고 해서 흥분해서 매도 하거나 하는 일은 없어야 한다.

    ELW는 사람이 하는 것이고 기계가 한다고 해도 설정되어 있는 기준은 사람이 만든것이다.

    ELW는 사람과 사람의 거래이니 절대적으로 감정을 억제하고 냉정하게 시장을 판단해야한다.

DDDW 컬럼의 표시값 파일저장시 가져오기

데이터윈도우이름.Describe("Evaluate('LookUpDisplay(컬럼명) ', " + String(행위치) + ")")

ELW 관한 기초

ELW는 증권사들이 자신들의 손해를 막기 위해서 개미들을 낚시 하는 것이다.

 

1. 시초 거래는 위험하다.

   단. 위험하지만 그날의 흐름을 1000% 알고 있다고 장담을 할수 있을 경우에만

   시초 9시 20분이전에 매수 거래를 들어갈수 있다고 가정한다.

 

2. 오버나이트 금지

   오버 즉 당일 매수한 ELW종목에 대해서 다음날까지 가져간다는 것은 매우 위험하다.

   특히 만기일이 10일 이하로 남았을 경우에는 하루 하루가 지날수록 잘못 오버 하게 되면

   5%~10%까지 프리(프리미엄)을 하락하고 들어가게 된다.

 

3. 매수는 신중히 하되 매도는 과감히 해야 한다.

   후회를 하는 순간부터 그 ELW에 집착을 하게 되면 집착은 감정을 통제를 못하게 이른다.

 

4. LP 보유율이 30%인 ELW 종목은 매수를 금지 해야 한다.

    단. 이익을 보았을 경우에 10%~5% 이익금으로 투기를 하는것은 자유이다.

 

5. LP 회원사가 어디 확인하고 그 해당 회원사의 거래 유형 패턴의 파악은 필수 이다.

   LP 회원사 끼리 서로 주고 받고 해서 거래량을 올려서 개미들을 낚시하는 경우가  대부분이다.

 

6. ELW 거래는 거래수수료만 존재 하면 세금은 존재 하지 않는다.

 

7. 지수ELW 기준으로 할경우 210 풋(PUT)일 경우에 각각의 손익 분기점이 있으므로

   만기 지수가 209라고 해서 절대로 안심 할수 없으며

   210콜(CALL)이라고 해서 만기 지수가 211이라고 해서 이익이 생기는 것은 절대 아니다.

   즉. 손익분기점을 확실히 알고 매매를 해야 한다.

 

8. 오버를 할경우에는 14시 30분 이후에 하자!

    14시 이후부터는 거래가 종료 되는 시점이 되기 때문에 자신이 다음일자에 열리는 장이

    콜,풋인지를 사는 것이 비교적 안전하다.

2010년 1월 7일 목요일

Pro-C 기초

이글은 초보자를 위한 것으로 Pro*C란 무엇인가를 설명해 놓은 것일 뿐입니다. 그냥 참조만 하시기 바랍니다.
 
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 as
scott/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 records
into 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 option
by 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 user
for an employee name and will display thr current sal and comm
fields 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 host
variable arrays. The arrays will be loaded with values
from 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 host
variable 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 row
from 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 the
salesman 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 a
WHERE clause to be used in an update statement. This is to be
used 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 a
WHERE clause to be used in an update statement. This is to be
used 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 a
WHERE clause to be used in a select statement.
This sample uses PREPARE, DECLARE, OPEN, FETCH, CLOSE
since 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    DESCRIPTION
Rem    
Rem    RETURNS
Rem 

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                        .c
IBM/VM/CMS         csql                       c
UNIX              .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