1. 程式人生 > >C語言訪問INFORMIX資料庫 — 介面實現

C語言訪問INFORMIX資料庫 — 介面實現

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

1 簡要概述

  INFORMIX資料庫是IBM旗下的一款關係資料庫,目前在金融行業佔有不可替代的地位。使用C語言訪問INFORMIX資料庫的唯一方式是通過ESQL,其過程中有很多細節內容需要注意,但為了能夠快速的理解各介面的流程,在此只給出各介面的基本框架。(注:ESQL語法在IBM幫助系統

http://publib.boulder.ibm.com/infocenter/idshelp/v10/index.jsp?中有詳盡的描述)


2 結構定義

/* 資料來源配置資訊 */typedef struct{ char svrname[DB_SVR_NAME_MAX_LEN];   /* 服務名 */ char usrname[DB_USR_NAME_MAX_LEN];   /* 使用者名稱 */ char passwd[DB_PWD_MAX_LEN];         /* 密碼 */
}db_source_struct_t;

/* 資料庫連線上下文資訊 */typedef struct{ char svrname[DB_SVR_NAME_MAX_LEN];         /* 服務名 */ char cnname[DB_CONN_NAME_MAX_LEN];         /* 連線名 */ /* 查詢結果集 */ ifx_sqlda_t *result;                       /* FETCH結果集 */
 int req_rows;                              /* 每次申請取的行數 */ int rows;                                  /* 結果集中實際的行數 */ int isalloced;                             /* 結果集空間是否被分配 0:未分配 1:已分配 */  /* 結果轉換 */ char *convert;                             /* 結果轉換空間 */ size_t convert_size;                       /* 結果轉換空間的大小 */ int msglen;                                /* 存放查詢資料的所有列的長度和 */ size_t row_size;                           /* 存放了在C程式中的所有列(一行)的長度和 */}db_ifx_cntx_t;

3 介面實現

3.1 連線資料庫

/* 連線至INFORMIX資料庫 */int db_ifx_open(db_sourct_t *source, db_ifx_cntx_t **context){    /* 連線資料庫 */    EXEC SQL CONNECT TO :svrname AS :cnname USER :usrname USING :passwd;    /* 啟用指定連線 */    EXEC SQL SET CONNECTION :cnname;    /* 開始事務 */    EXEC SQL BEGIN WORK;}

說明:
  1. 以上函式中的宿主變數svrname(服務名)、usrname(使用者名稱)、passwd(登入密碼)、cnname(連線名),這些變數的定義可參考:http://blog.csdn.net/royalapex/article/details/8201699
  2. 一個程序中可以有多個數據庫連線,各資料庫連線是通過連線名進行識別(區別、區分)的

3.2 斷開連線

/* 斷開與INFORMIX資料庫的連線 */int db_ifx_close(db_ifx_cntx_t *context){    EXEC SQL COMMIT WORK;    EXEC SQL DISCONNECT :cnname;}

說明:
  1. 在連線資料庫時,開啟了事務,在斷開連線時,應該關閉事務

3.3 提交事務

/* 提交事務 */int db_ifx_commit(db_ifx_cntx_t *context){    /* 提交事務 */    EXEC SQL COMMIT WORK;    /* 開始事務 */    EXEC SQL BEGIN WORK;}

說明:
  1. 斷開連線時,關閉事務;故:提交事務後,需開啟新的事務

3.4 回滾事務

/* 回滾事務 */int db_ifx_rollback(void *context){    /* 回滾事務 */    EXEC SQL ROLLBACK WORK;    /* 開始事務 */    EXEC SQL BEGIN WORK;}

說明:
  1. 斷開連線時,關閉事務;故:回滾事務後,需開啟新的事務

3.5 動態SQL:非查詢語句

/* 執行非查詢的動態SQL語句 */int db_ifx_nquery(const char *sql, db_ifx_cntx_t *context){EXEC SQL BEGIN DECLARE SECTION;    char sql_stmt[SQL_STMT_MAX_LEN] = {0};EXEC SQL END DECLARE SECTION;    snprintf(sql_stmt, sizeof(sql_stmt), "%s", sql);    /* 準備動態SQL語句 */    EXEC SQL PREPARE NQUERY_SQLSTMT_ID FROM :sql_stmt;    /* 執行:非查詢SQL */    EXEC SQL EXECUTE NQUERY_SQLSTMT_ID}

說明:
  1. 執行動態非查詢SQL的過程是:PREPARE動態語句, 再執行非查詢SQL

3.6 動態SQL:查詢語句

/* 執行一個動態查詢sql(多行查詢) */int db_ifx_mquery(const char *sql, db_ifx_cntx_t *context){EXEC SQL BEGIN DECLARE SECTION;  char sql_stmt[SQL_STMT_MAX_LEN];EXEC SQL END DECLARE SECTION;  int ret = -1ifx_sqlda_t *sqlda = NULL;  snprintf(sql_stmt, sizeof(sql_stmt), "%s", sql); /* Step 1: PREPARE查詢語句 */  EXEC SQL PREPARE QUERY_SQLSTMT_ID FROM :sql_stmt;  /* Step 2: 使用describe函式完成兩個功能:  1. 為sqlda分配空間,   2. 獲取語句資訊,並存放在ifx_sqlda_t結構中 */  EXEC SQL DESCRIBE QUERY_SQLSTMT_ID INTO sqlda; do {  /* Step 3: 初始化結果集 */  ret = db_ifx_init_result(context, sqlda);     /* Step 4: 宣告和開啟遊標 */   ret = db_ifx_declare(context);   ret = db_ifx_copen(context);    return sqlda->sqld; }while(0); db_ifx_free_sqlda(sqlda), sqlda = NULLreturn -1;}

說明:
  1. DESCRIBE: 為SQLDA分配空間,並獲取語句資訊,並存放在SQLDA結構中,資訊包括:
      1) 列數

      2) 為struct sqlvar_struct結構分配sqld個空間,但未該結構體中的指標分配空間

      3) 資料型別

      4) 列長度等已初始化
  2. 關於db_ifx_sqlda_t的結構,可參考:http://blog.csdn.net/royalapex/article/details/8205654
  3. 關於db_ifx_sqlda_t的使用,可參考:http://blog.csdn.net/royalapex/article/details/8210965
  4. QUERY_SQLSTMT_ID:語句ID

3.7 定義遊標

/* 宣告遊標 */int db_ifx_declare(db_ifx_cntx_t *context){  EXEC SQL DECLARE QUERY_CURSOR_ID CURSOR FOR QUERY_SQLSTMT_ID;}

說明:
  1. QUERY_CURSOR_ID:遊標ID
  2. QUERY_SQLSTMT_ID:語句ID

3.8 開啟遊標

/* 開啟遊標 */int db_ifx_copen(db_ifx_cntx_t *context){  EXEC SQL OPEN QUERY_CURSOR_ID; }

說明:
  1. QUERY_CURSOR_ID:遊標ID

3.9 獲取資料(FETCH)

/* 取出一個動態查詢sql遊標的一條記錄  (返回值:0:未取到資料 1:取到一條 -1:失敗) */int db_ifx_fetch(db_ifx_cntx_t *context)ifx_sqlda_t *sqlda = (ifx_sqlda_t *)context->result; /* 1: 執行fetch操作,將資料存放在sqlda結構中 */ EXEC SQL FETCH QUERY_CURSOR_ID USING DESCRIPTOR sqlda; if(SQLNOTFOUND == sqlca.sqlcode) {  return 0; } else if(0 != sqlca.sqlcode) {  return -1; }  return 1;}

說明:
  1. QUERY_CURSOR_ID:遊標ID

4.10 關閉遊標

/* 釋放遊標 */int db_ifx_cclose(db_ifx_cntx_t *context) {  /* 關閉遊標 */ EXEC SQL CLOSE QUERY_CURSOR_ID; EXEC SQL FREE QUERY_CURSOR_ID;}

說明:
  1. QUERY_CURSOR_ID:遊標ID 

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述