首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Pro*C 編程實戰筆記:環境配置、數據類型映射、數組操作與預編譯選項全攻略

     編輯:關於C語言

Pro*C 作為 Oracle 嵌入式 SQL 的經典實現,在存量系統維護中仍佔重要地位。本文匯總環境變量、類型映射、數組 FETCH/INSERT、動態 SQL、預編譯選項等工程級知識點。

一、運行環境變量配置

ORACLE_SID=ORA8
NLS_LANG=American_America.ZHS16CGB231280  # 字符集關鍵
ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data
ORACLE_HOME=/home/oracle
LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib:.
SHLIB_PATH=$ORACLE_HOME/lib
NLS_DATE_FORMAT='YYYY/MM/DD'

字符集不匹配 是亂碼首因,客戶端 NLS_LANG 必須與數據庫字符集兼容。

二、遷移注意事項

差異點InformixOracle Pro*C
字符串界定符雙引號 "單引號 ' (雙引號報錯)
長字符串截斷自動截斷報錯 ORA-12899
VARCHAR 等價聲明無需EXEC SQL VAR name IS STRING(n);
宏定義EXEC SQL DEFINE用 EXEC ORACLE DEFINE 或 C 常量

三、關鍵預編譯選項

四、數據類型映射速查

選項推薦值說明
MODEANSI標準合規,游標語義嚴格
CHAR_MAPSTRINGchar[n] 自動視為以 \0 結尾,免去 VARCHAR 等價聲明
RELEASE_CURSORYES提交/回滾後釋放游標,防洩漏
HOLD_CURSORNO不長期持有游標
MAXOPENCURSORS50+根據併發游標數調整
SQLCHECKSEMANTICS連接數據庫做語義檢查(需有效 schema)
PARSEFULL完整解析 C 代碼(支援 #include 等)
THREADSYES多線程程序必開
Oracle 類型C 類型Pro*C 外部類型備註
VARCHAR2(n)char[n+1]STRING / CHARZ需 +1 存 \0
CHAR(n)char[n]CHARF定長,不自動補 \0
NUMBERint/long/float/doubleINTEGER/FLOAT視精度選擇
NUMBER(p,s)doubleFLOAT高精度建議字符串讀取
DATEchar[11+]STRING格式由 NLS_DATE_FORMAT 決定
RAW(n)unsigned char[n]RAW二進制數據
ROWIDchar[19+]STRING18字符+ \0

五、數組操作核心模式

1. 靜態數組 FETCH

#define MAX_ROWS 1000
long id[MAX_ROWS];
char name[MAX_ROWS][31];
short id_ind[MAX_ROWS];
short name_ind[MAX_ROWS];

EXEC SQL FOR :MAX_ROWS FETCH cur INTO :id:id_ind, :name:name_ind;
int fetched = sqlca.sqlerrd[2];  // 實際提取行數

2. 數組 INSERT

int ids[100];
char names[100][31];
for (int i=0; i<100; i++) { ids[i]=i; sprintf(names[i], "name%d", i); }
EXEC SQL FOR :100 INSERT INTO t (id, name) VALUES (:ids, :names);

3. 結構體數組(推薦)

struct Emp { int id; char name[31]; } emps[100];
Emp *p = emps;  // 必須用指針
EXEC SQL FOR :100 SELECT id, name INTO :p FROM emp WHERE rownum <= 100;
  • 結構體成員順序/類型/數量必須與 SELECT 列完全一致
  • 指針指向數組首元素

4. 動態 SQL 中使用數組

char *sql = "INSERT INTO t (id) VALUES (:v)";
EXEC SQL PREPARE stmt FROM :sql;
EXEC SQL FOR :100 EXECUTE stmt USING :ids;

六、存儲過程調用

EXEC SQL EXECUTE
BEGIN
  my_pkg.proc(:in_param, :out_param, :inout_param);
END;
END-EXEC;
  • PL/SQL 塊包裹在 EXEC SQL EXECUTE ... END-EXEC
  • IN/OUT/INOUT 參數均用宿主變量綁定

七、Makefile 模板

ORACLE_HOME = /oracle/app/oracle/product/19c
PROC = $(ORACLE_HOME)/bin/proc
PROCFLAGS = parse=FULL sqlcheck=SEMANTICS char_map=STRING release_cursor=YES userid=scott/tiger

CC = gcc
CFLAGS = -I$(ORACLE_HOME)/precomp/public -I$(ORACLE_HOME)/rdbms/public
LDFLAGS = -L$(ORACLE_HOME)/lib -lclntsh

.SUFFIXES: .pc .c .o

.pc.c:
	$(PROC) $(PROCFLAGS) iname=$<

.c.o:
	$(CC) $(CFLAGS) -c $<

myapp: main.o db.o util.o
	$(CC) -o $@ $^ $(LDFLAGS)

八、常見 sqlca 字段

  • sqlcode:0 成功,>0 異常 (1403 NOT FOUND),<0 錯誤
  • sqlerrm.sqlerrmc:錯誤消息文本
  • sqlerrd[2]:已處理行數 (INSERT/UPDATE/DELETE/FETCH 累積)
  • sqlerrd[4]:游標緩存統計
  • sqlwarn[0]:'W' 表示有警告

總結

Pro*C 核心在於宿主變量聲明區 (DECLARE SECTION)、類型等價 (VAR IS STRING)、游標生命週期管理、數組批量操作。現代化替代方案:OCCI (C++)、ODPI-C (輕量 C)、微服務化。維護舊系統時,嚴格遵循 MODE=ANSI、CHAR_MAP=STRING、RELEASE_CURSOR=YES 三大鐵律,能消除 90% 的游標洩漏與字符串截斷問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved