Oracle Database Development (3). Introduce to Pro*C/C++ Precompiler Options
Vert Melon
Jun 7,2007
1.Preface
Now we have already known about the Pro*C/C++ Development Environment in Windows
or Linux, but it is not enough.
Anyway, esaier said than done, let's start our trip.
2.What is the Precompiler
During precompilation, Pro*C/C++ generates C or C++ code that replaces the SQL
statements embedded in your host program. The generated code contains data structures
that indicate the datatype, length, and address of host variables, as well as other
information required by the runtime library, SQLLIB. The generated code also contains
the calls to SQLLIB routines that perform the embedded SQL operations.
The precompiler does not generate calls to Oracle Call Interface (OCI) routines.
The paragraph above is copied from 《Pro*C/C++ Precompiler Programmer's Guide》. I'm
clever at doing this ^_^ .
SQLLIB named "orasql9.lib" in Windows, but named "libclntsh.so.9.0" in Linux.
You could get more messages if your find it in the last articles within this series.
Oracle Database Development (1). Configuration of ProC in Windows
Oracle Database Development (2). Configuration of ProC in Linux
3.Use the Precompiler Options
Precompiler options enable you to control how resources are used, how errors are reported,
how input and output are formatted, and how cursors are managed.
In the Windows , most people prefer to use "procui.exe" to precompile host program.
Of course , the tool provides "Options" menu which gives us a platform to edit options.
When we use Linux OS, we can appoint the parameters in the command line. For example :
$ proc parse=none iname=main.pc
Developer can get more information by typing command " proc ? " in both Windows and Linux.
The method mentioned above is only one of the Using Precompiler Option, which i can
call it "command line" .
In Oralce, there are many methods like this , such as :
system configuration file
user configuration file
command line
inline
There is a single system configuration file for each installation. The name of the
system configuration file is pcscfg.cfg. The directory of the file is "$ORACLE_HOME/precomp/admin" .
We can specifies the name of a user configuration file by using the CONFIG option.
"inline" means that the declaration is in the host program. This statements begin
with "EXEC SQL" ,and not every option can be declared as "inline".
The precedence of option values is explained indisputably in Oracle referential document.
I don't want to waste so much time talking about the usage because of the 《Pro*C/C++ Precompiler Programmer's Guide》.
ORAC
Luckily, i am not so stupid to forget my original purpose. Here comes the key .
4.The Important Options
CONFIG , PARSE and SYS_INCLUDE
Type the command "proc ?" and take a overview of the description , you will find
that the default value of CONFIG is null. Oracle always use the system configuration
file except CONFIG is defined .
In Linux OS environment , the default file named "pcscfg.cfg" includes the option
"SYS_INCLUDE" . But if PARSE=NONE , this option is irrelevant for the precompilation.
That is the reason you can use "proc parse=none iname=main.pc" precompile the host
program so easily.
When PARSE=FULL , your must define the value of SYS_INCLUDE , and then you can
declare host variables legally in C.
#include "sqlca.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void sql_error(char *msg)
{
printf("/n%s %s/n", msg,(char *)sqlca.sqlerrm.sqlerrmc);
//EXEC SQL ROLLBACK RELEASE;
exit(0);
}
void main() {
EXEC SQL INCLUDE sqlca;
EXEC ORACLE OPTION (RELEASE_CURSOR = YES);
EXEC SQL WHENEVER SQLERROR DO sql_error(" <ERROR> ");
char oraCN[200];
strcpy(oraCN, "system/ddd@unixdb");
EXEC SQL CONNECT :oraCN;
printf("/n [OK Connected!] ");
}
In Windows OS , maybe the value is "E:/Program Files/Microsoft Visual Studio/VC98/Include" .
Edit the "pcscfg.cfg" file and precomplie the code above . The programe runs
very good.
The case becomes a litter complex in Linux .
$ pwd
/home/ora/ora9/oracle/precomp/admin
$ cat pcscfg.cfg
sys_include=(/usr/include,/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include)
ltype=short
$ proc parse=full iname=main.pc
$ gcc -g -o main main.c -I/home/ora/ora9/oracle/precomp/public -L/home/ora/ora9/oracle/lib -lclntsh
It runs very good too .
------------------------------------------------------
Oracle refrence
PARSE=NONE
The value NONE has the following effects:
C preprocessor directives are understood only inside a declare section.
You must declare all host variables inside a Declare Section.
Precompiler release 1.x behavior
PARSE=PARTIAL
The value PARTIAL has the following effects:
All preprocessor directives are understood
You must declare all host variables inside a Declare Section
This option value is the default if CODE=CPP
PARSE=FULL
The value FULL has the following effects:
The precompiler C parser runs on your code.
All Preprocessor directives are understood.
You can declare host variables at any place that they can be declared legally in C.
5.Postscript
When I used the option "PARSE=FULL" , i found that "EXEC SQL INCLUDE sqlca;"
"EXEC SQL ROLLBACK RELEASE; " cannot be precompled correctly together.
I have no idea about it . Perhaps it caused by the internal compatibility of SQLCA.
I am sure i will work along with it.
Oracle資料庫開發(三).ProC的先行編譯參數
草木瓜
20070607
一、前言
我們上面已經瞭解Windows和Linux下的ProC開發環境,這裡我們更進一步去
簡要介紹下ProC的先行編譯參數。
二、什麼是先行編譯
先行編譯過程中,Pro*C/C++會自動產生C或者C++的代碼,去替代你原來的嵌入SQL,
產生的程式碼包含了一些資料結構,其中聲明了資料類型,長度,變數地址以及SQLLIB需
要的一些其他資訊。產生的程式碼還包括了執行嵌入SQL操作的一些SQLLIB調用。
SQLLIB Windows下名是 "orasql9.lib" ,Linux下是"libclntsh.so.9.0" 。這方面知識可以參
考先前的文章:
《Oracle資料庫開發(一).Windows下配置使用ProC》
《Oracle資料庫開發(二).Linux下配置使用ProC》
三、使用先行編譯選項
先行編譯選項可以控制編譯資源的使用,錯誤提示,標準化輸入輸出以及管理遊標。
在Windows下,多數人傾向於使用“procui.exe”(Oralce菜單裡的ProC*C++工具)進行
先行編譯,可以通過Options菜單選擇編譯選項。當我們使用Linux平台時,一般會在命
令行下指定參數,例如:
$ proc parse=none iname=main.pc
不管是Windows還是Linux,開發人員可以都鍵入“proc ?”擷取更多的資訊。
在Oracle中,關於參數的使用有不少的方法,如:
系統參數檔案
使用者參數檔案
命令列
inline
ProC安裝後都會存在唯一的系統參數檔案“pcscfg.cfg”,所在路徑為“$ORACLE_HOME/precomp/admin”。
使用者的參數檔案,我們可以手工指定。命令列很容易理解,上面已有相關說明。“inline”
的意思是在原始pc檔案中通過“EXEC SQL”顯式聲明,不過不是所有的參數可以使用
這種方式聲明。
關於這些優先順序的說明,在Oracle相關的官方文檔已經說得很明確。具體內容可
參看《Pro*C/C++開發指南》,這裡不再贅述。
四、一些比較重要的參數
CONFIG,PARSE 和 SYS_INCLUDE
在命令列下輸入“proc ?”,簡單瀏覽下顯示資訊,你會發現CONFIG的預設值是空。
ORACLE一直使用的是系統的參數檔案,除非你手工去指定config選項。
在Linux環境下,預設的系統參數檔案“pcscfg.cfg”中含有“SYS_INCLUDE”的選項,
但是如果“PARSE=NONE",這個“SYS_INCLUDE”的選項會被忽略。所以你可以使用
“proc parse=none iname=main.pc”(上篇文章)輕鬆編譯。
不過當我們指定PARSE值為FULL時,你就必須正確定義“SYS_INCLUDE”,這時可
以在ProC的源檔案.pc中,直接使用C文法規則定義宿主變數。可以看下面的例子:
#include "sqlca.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void sql_error(char *msg)
{
printf("/n%s %s/n", msg,(char *)sqlca.sqlerrm.sqlerrmc);
//EXEC SQL ROLLBACK RELEASE;
exit(0);
}
void main() {
EXEC SQL INCLUDE sqlca;
EXEC ORACLE OPTION (RELEASE_CURSOR = YES);
EXEC SQL WHENEVER SQLERROR DO sql_error(" <ERROR> ");
char oraCN[200];
strcpy(oraCN, "system/ddd@unixdb");
EXEC SQL CONNECT :oraCN;
printf("/n [OK Connected!] ");
}
在Windows下,“SYS_INCLUDE"的值類似於“E:/Program Files/Microsoft Visual Studio/VC98/Include”,
即Vc6.0的標頭檔目錄,編輯“pcscfg.cfg”,然後先行編譯原始碼,程式運行沒有任何問題。
在Linux下,可能要稍微複雜一些。
$ pwd
/home/ora/ora9/oracle/precomp/admin
$ cat pcscfg.cfg
sys_include=(/usr/include,/usr/lib/gcc-lib/i386-redhat-linux/3.2.2/include)
ltype=short
$ proc parse=full iname=main.pc
$ gcc -g -o main main.c -I/home/ora/ora9/oracle/precomp/public -L/home/ora/ora9/oracle/lib -lclntsh
依上編譯,也沒有問題。
------------------------------------------------------
Oracle 參考
PARSE=NONE
所有宿主變數必須定義在聲明段中。只有在聲明段中的先行編譯指令才會
識別。
PARSE=PARTIAL
可以識別所有的先行編譯指令,所有宿主變數必須定義在聲明段中。如果
CODE=CPP,這個是預設選項。
PARSE=FULL
可以識別所有的先行編譯指令,可以直接使用C文法定義宿主變數,不必
定義在聲明段中。
五、後記
在我使用“PARSE=FULL”選項時,發現“EXEC SQL INCLUDE sqlca;” 和 “EXEC SQL ROLLBACK RELEASE; ”
不能同時使用。不知道是為什麼,估計可能是SQLCA的內部相容性問題。相信有時
間能解決這個問題。