Pro*C/C++ 是 Oracle 提供的預編譯器,允許在 C/C++ 程式碼中直接嵌入 SQL 陳述式,經預編譯轉換為純 C/C++ 程式碼,再由一般編譯器編譯連結。嵌入式 SQL 即在宿主語言(Host Language)中使用 SQL,SQL 標準定義了多種語言的嵌入方式,各廠商實作細節不同。
| 宿主語言 | 預編譯器 |
|---|---|
| C/C++ | Pro*C/C++ |
| FORTRAN | Pro*FORTRAN |
| PASCAL | Pro*PASCAL |
| COBOL | Pro*COBOL |
| PL/I | Pro*PL/I |
| Ada | Pro*Ada |
需設定 $ORACLE_HOME/precomp/admin/pcscfg.cfg 組態檔,確認路徑正確。
dm01_hello.pc#include <stdio.h>
#include <string.h>
#include "sqlca.h"
EXEC SQL BEGIN DECLARE SECTION;
char *serverid = "scott/123456@orcl";
EXEC SQL END DECLARE SECTION;
int main() {
int ret = 0;
printf("hello....\n");
printf("serverid:%s \n", serverid);
EXEC SQL connect :serverid;
if (sqlca.sqlcode != 0) {
ret = sqlca.sqlcode;
printf("EXEC SQL connect:err, %d\n", ret);
return ret;
}
printf("connect ok\n");
return ret;
}
EXEC SQL BEGIN/END DECLARE SECTION:宣告宿主變數區段,供 SQL 陳述式引用。:serverid:冒號前綴表示使用 C 變數。sqlca.sqlcode:SQL 通訊區回傳碼,0 表成功。proc dm01_hello.pc # 產生 dm01_hello.c
gcc dm01_hello.c -o dm01_hello \
-I$ORACLE_HOME/precomp/public \
-L$ORACLE_HOME/lib -lclntsh
./dm01_hello # 執行
-lclntsh 連結 clntsh.so。lsnrctl start 並確認資料庫 startup。| 選項 | 說明 |
|---|---|
| INAME | 輸入檔路徑與檔名 |
| ONAME | 輸出檔路徑與檔名 |
| INCLUDE | 標頭檔搜尋路徑 |
| PARSE | FULL/PARTIAL/NONE,C++ 需設 PARTIAL 或 NONE |
| CODE | ANSI_C 或 CPP |
| USERID | 連線帳號/密碼 |
需指定 PARSE=NONE CODE=CPP,輸出 .cc 副檔名,再用 g++ 編譯連結。
all: dm01_hello dm02_hello
dm01_hello:
@echo 'proc dm01_hello begin'
proc dm01_hello.pc
@echo 'gcc dm01_hello begin'
gcc dm01_hello.c -o dm01_hello -I${ORACLE_HOME}/precomp/public -L${ORACLE_HOME}/lib -lclntsh
dm02_hello:
@echo 'proc dm02_hello begin'
proc iname=./dm02_hello.pc oname=dm02_hello.cc PARSE=NONE CODE=CPP
@echo 'g++ dm02_hello begin'
g++ dm02_hello.cc -o dm02_hello -I${ORACLE_HOME}/precomp/public -L${ORACLE_HOME}/lib -lclntsh
clean:
@rm dm01_hello dm02_hello
執行 make 即可一鍵完成預編譯、編譯、連結。
以 dept 表為例,示範 Insert、Delete、Update、Select 操作,皆使用宿主變數綁定,並以 EXEC SQL COMMIT RELEASE 提交交易並斷線。
EXEC SQL insert into dept (deptno, dname, loc) values(:deptno, :dname, :loc);
EXEC SQL commit;
EXEC SQL delete from dept where deptno=:deptno;
EXEC SQL commit;
EXEC SQL update dept set loc = :loc where deptno=:deptno;
EXEC SQL commit;
EXEC SQL select deptno, dname, loc
into :deptno2, :dname2, :loc2
from dept where deptno=:deptno;
透過 Makefile 管理多支程式,搭配 information_schema.columns 動態查詢分表名稱,即可彈性處理按月分表等實務場景。