Informix ESQL/C 允許在 C 程式中嵌入 SQL 語句,透過預處理器 (esql) 轉換為標準 C 代碼。掌握其特定的聲明區段、宏定義與錯誤處理機制,是開發穩健資料庫應用的基礎。
使用 EXEC SQL INCLUDE 引入 Informix 提供的標準定義檔,等同於 C 的 #include 但會經過 ESQL 預處理:
[cpp]
EXEC SQL INCLUDE sqlca; // SQL 通訊區 (錯誤碼、狀態)
EXEC SQL INCLUDE sqlda; // SQL 描述區 (動態 SQL 用)
EXEC SQL INCLUDE sqlhdr; // 通用標頭定義
EXEC SQL INCLUDE decimal; // DECIMAL 型別處理
EXEC SQL INCLUDE locator; // BLOB/CLOB 定位器
EXEC SQL INCLUDE varchar; // VARCHAR 型別處理
EXEC SQL INCLUDE datetime; // DATE/TIME 型別處理
EXEC SQL INCLUDE sqlstype; // SQL 資料型別代碼
EXEC SQL INCLUDE sqltypes; // SQL 型別映射
使用 EXEC SQL DEFINE 定義編譯期常數,供宿主變量聲明使用,增強可維護性:
[cpp]
EXEC SQL DEFINE SQL_USRNAME_MAX_LEN 64; // 使用者名稱最大長度
EXEC SQL DEFINE SQL_PASSWD_MAX_LEN 64; // 密碼最大長度
EXEC SQL DEFINE SQL_SVRNAME_MAX_LEN 64; // 資料庫伺服器名稱最大長度
EXEC SQL DEFINE SQL_CNNAME_MAX_LEN 64; // 連線名稱最大長度
EXEC SQL DEFINE SQL_STMT_MAX_LEN 1024; // SQL 陳述式最大長度
當 SQL 陳述式需使用結構體變量時,必須在 DECLARE SECTION 區塊中定義型別:
[cpp]
EXEC SQL BEGIN DECLARE SECTION;
typedef struct {
int id;
char name[32];
char gender;
int age;
char brf[256];
} DBStudent_t;
EXEC SQL END DECLARE SECTION;
使用範例:更新資料表
[cpp]
int db_ifx_update(...)
{
EXEC SQL BEGIN DECLARE SECTION;
DBStudent_t dbstudent;
EXEC SQL END DECLARE SECTION;
// ...
EXEC SQL UPDATE student SET *=(:dbstudent) WHERE id='10001';
}
所有與 SQL 互動的 C 變量 (輸入/輸出) 必須在 DECLARE SECTION 內聲明:
[cpp]
EXEC SQL BEGIN DECLARE SECTION;
char svrname[SQL_SVRNAME_MAX_LEN]; // Server name
char usrname[SQL_USRNAME_MAX_LEN]; // User name
char passwd[SQL_PASSWD_MAX_LEN]; // Password
char cnname[SQL_CNNAME_MAX_LEN]; // Connection name
EXEC SQL END DECLARE SECTION;
連線範例:
[cpp]
int db_ifx_open(...)
{
EXEC SQL BEGIN DECLARE SECTION;
char svrname[SQL_SVRNAME_MAX_LEN];
char usrname[SQL_USRNAME_MAX_LEN];
char passwd[SQL_PASSWD_MAX_LEN];
char cnname[SQL_CNNAME_MAX_LEN];
EXEC SQL END DECLARE SECTION;
// ...
EXEC SQL CONNECT TO :svrname AS :cnname USER :usrname USING :passwd;
// ...
}
每執行一條 SQL 語句後,錯誤碼存放於全域變量 sqlca.sqlcode:
sqlcode == 0:成功sqlcode > 0:警告 (如 NOT FOUND)sqlcode < 0:錯誤使用 rgetmsg() 取得錯誤訊息字串:
[cpp]
int db_ifx_commit(...)
{
EXEC SQL COMMIT WORK;
if (sqlca.sqlcode < 0) {
char errmsg[256];
rgetmsg(sqlca.sqlcode, errmsg, sizeof(errmsg));
fprintf(stdout, "%s", errmsg);
return -1;
}
// ...
}
EXEC SQL 後緊接錯誤檢查,防止靜默失敗。