示例

常用功能示例代码

  1. // 此示例演示如何通过ODBC方式获取openGauss中的数据。
  2. // DBtest.c (compile with: libodbc.so)
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <sqlext.h>
  6. #ifdef WIN32
  7. #include <windows.h>
  8. #endif
  9. SQLHENV V_OD_Env; // Handle ODBC environment
  10. SQLHSTMT V_OD_hstmt; // Handle statement
  11. SQLHDBC V_OD_hdbc; // Handle connection
  12. char typename[100];
  13. SQLINTEGER value = 100;
  14. SQLINTEGER V_OD_erg,V_OD_buffer,V_OD_err,V_OD_id;
  15. int main(int argc,char *argv[])
  16. {
  17. // 1. 申请环境句柄
  18. V_OD_erg = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&V_OD_Env);
  19. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
  20. {
  21. printf("Error AllocHandle\n");
  22. exit(0);
  23. }
  24. // 2. 设置环境属性(版本信息)
  25. SQLSetEnvAttr(V_OD_Env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
  26. // 3. 申请连接句柄
  27. V_OD_erg = SQLAllocHandle(SQL_HANDLE_DBC, V_OD_Env, &V_OD_hdbc);
  28. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
  29. {
  30. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
  31. exit(0);
  32. }
  33. // 4. 设置连接属性
  34. SQLSetConnectAttr(V_OD_hdbc, SQL_ATTR_AUTOCOMMIT, SQL_AUTOCOMMIT_ON, 0);
  35. // 5. 连接数据源,这里的“userName”与“password”分别表示连接数据库的用户名和用户密码,请根据实际情况修改。
  36. // 如果odbc.ini文件中已经配置了用户名密码,那么这里可以留空("");但是不建议这么做,因为一旦odbc.ini权限管理不善,将导致数据库用户密码泄露。
  37. V_OD_erg = SQLConnect(V_OD_hdbc, (SQLCHAR*) "gaussdb", SQL_NTS,
  38. (SQLCHAR*) "userName", SQL_NTS, (SQLCHAR*) "password", SQL_NTS);
  39. if ((V_OD_erg != SQL_SUCCESS) && (V_OD_erg != SQL_SUCCESS_WITH_INFO))
  40. {
  41. printf("Error SQLConnect %d\n",V_OD_erg);
  42. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
  43. exit(0);
  44. }
  45. printf("Connected !\n");
  46. // 6. 设置语句属性
  47. SQLSetStmtAttr(V_OD_hstmt,SQL_ATTR_QUERY_TIMEOUT,(SQLPOINTER *)3,0);
  48. // 7. 申请语句句柄
  49. SQLAllocHandle(SQL_HANDLE_STMT, V_OD_hdbc, &V_OD_hstmt);
  50. // 8. 直接执行SQL语句。
  51. SQLExecDirect(V_OD_hstmt,"drop table IF EXISTS customer_t1",SQL_NTS);
  52. SQLExecDirect(V_OD_hstmt,"CREATE TABLE customer_t1(c_customer_sk INTEGER, c_customer_name VARCHAR(32));",SQL_NTS);
  53. SQLExecDirect(V_OD_hstmt,"insert into customer_t1 values(25,li)",SQL_NTS);
  54. // 9. 准备执行
  55. SQLPrepare(V_OD_hstmt,"insert into customer_t1 values(?)",SQL_NTS);
  56. // 10. 绑定参数
  57. SQLBindParameter(V_OD_hstmt,1,SQL_PARAM_INPUT,SQL_C_SLONG,SQL_INTEGER,0,0,
  58. &value,0,NULL);
  59. // 11. 执行准备好的语句
  60. SQLExecute(V_OD_hstmt);
  61. SQLExecDirect(V_OD_hstmt,"select id from testtable",SQL_NTS);
  62. // 12. 获取结果集某一列的属性
  63. SQLColAttribute(V_OD_hstmt,1,SQL_DESC_TYPE,typename,100,NULL,NULL);
  64. printf("SQLColAtrribute %s\n",typename);
  65. // 13. 绑定结果集
  66. SQLBindCol(V_OD_hstmt,1,SQL_C_SLONG, (SQLPOINTER)&V_OD_buffer,150,
  67. (SQLLEN *)&V_OD_err);
  68. // 14. 通过SQLFetch取结果集中数据
  69. V_OD_erg=SQLFetch(V_OD_hstmt);
  70. // 15. 通过SQLGetData获取并返回数据。
  71. while(V_OD_erg != SQL_NO_DATA)
  72. {
  73. SQLGetData(V_OD_hstmt,1,SQL_C_SLONG,(SQLPOINTER)&V_OD_id,0,NULL);
  74. printf("SQLGetData ----ID = %d\n",V_OD_id);
  75. V_OD_erg=SQLFetch(V_OD_hstmt);
  76. };
  77. printf("Done !\n");
  78. // 16. 断开数据源连接并释放句柄资源
  79. SQLFreeHandle(SQL_HANDLE_STMT,V_OD_hstmt);
  80. SQLDisconnect(V_OD_hdbc);
  81. SQLFreeHandle(SQL_HANDLE_DBC,V_OD_hdbc);
  82. SQLFreeHandle(SQL_HANDLE_ENV, V_OD_Env);
  83. return(0);
  84. }

批量绑定示例代码

  1. /**********************************************************************
  2. * 请在数据源中打开UseBatchProtocol,同时指定数据库中参数support_batch_bind
  3. * 为on
  4. * CHECK_ERROR的作用是检查并打印错误信息。
  5. * 此示例将与用户交互式获取DSN、模拟的数据量,忽略的数据量,并将最终数据入库到test_odbc_batch_insert中
  6. ***********************************************************************/
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <sql.h>
  10. #include <sqlext.h>
  11. #include <string.h>
  12. #include "util.c"
  13. void Exec(SQLHDBC hdbc, SQLCHAR* sql)
  14. {
  15. SQLRETURN retcode; // Return status
  16. SQLHSTMT hstmt = SQL_NULL_HSTMT; // Statement handle
  17. SQLCHAR loginfo[2048];
  18. // Allocate Statement Handle
  19. retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
  20. CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)",
  21. hstmt, SQL_HANDLE_STMT);
  22. // Prepare Statement
  23. retcode = SQLPrepare(hstmt, (SQLCHAR*) sql, SQL_NTS);
  24. sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql);
  25. CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT);
  26. // Execute Statement
  27. retcode = SQLExecute(hstmt);
  28. sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql);
  29. CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT);
  30. // Free Handle
  31. retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
  32. sprintf((char*)loginfo, "SQLFreeHandle stmt log: %s", (char*)sql);
  33. CHECK_ERROR(retcode, loginfo, hstmt, SQL_HANDLE_STMT);
  34. }
  35. int main ()
  36. {
  37. SQLHENV henv = SQL_NULL_HENV;
  38. SQLHDBC hdbc = SQL_NULL_HDBC;
  39. int batchCount = 1000;
  40. SQLLEN rowsCount = 0;
  41. int ignoreCount = 0;
  42. SQLRETURN retcode;
  43. SQLCHAR dsn[1024] = {'\0'};
  44. SQLCHAR loginfo[2048];
  45. // 交互获取数据源名称
  46. getStr("Please input your DSN", (char*)dsn, sizeof(dsn), 'N');
  47. // 交互获取批量绑定的数据量
  48. getInt("batchCount", &batchCount, 'N', 1);
  49. do
  50. {
  51. // 交互获取批量绑定的数据中,不要入库的数据量
  52. getInt("ignoreCount", &ignoreCount, 'N', 1);
  53. if (ignoreCount > batchCount)
  54. {
  55. printf("ignoreCount(%d) should be less than batchCount(%d)\n", ignoreCount, batchCount);
  56. }
  57. }while(ignoreCount > batchCount);
  58. retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
  59. CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_ENV)",
  60. henv, SQL_HANDLE_ENV);
  61. // Set ODBC Verion
  62. retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION,
  63. (SQLPOINTER*)SQL_OV_ODBC3, 0);
  64. CHECK_ERROR(retcode, "SQLSetEnvAttr(SQL_ATTR_ODBC_VERSION)",
  65. henv, SQL_HANDLE_ENV);
  66. // Allocate Connection
  67. retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
  68. CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_DBC)",
  69. henv, SQL_HANDLE_DBC);
  70. // Set Login Timeout
  71. retcode = SQLSetConnectAttr(hdbc, SQL_LOGIN_TIMEOUT, (SQLPOINTER)5, 0);
  72. CHECK_ERROR(retcode, "SQLSetConnectAttr(SQL_LOGIN_TIMEOUT)",
  73. hdbc, SQL_HANDLE_DBC);
  74. // Set Auto Commit
  75. retcode = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT,
  76. (SQLPOINTER)(1), 0);
  77. CHECK_ERROR(retcode, "SQLSetConnectAttr(SQL_ATTR_AUTOCOMMIT)",
  78. hdbc, SQL_HANDLE_DBC);
  79. // Connect to DSN
  80. sprintf(loginfo, "SQLConnect(DSN:%s)", dsn);
  81. retcode = SQLConnect(hdbc, (SQLCHAR*) dsn, SQL_NTS,
  82. (SQLCHAR*) NULL, 0, NULL, 0);
  83. CHECK_ERROR(retcode, loginfo, hdbc, SQL_HANDLE_DBC);
  84. // init table info.
  85. Exec(hdbc, "drop table if exists test_odbc_batch_insert");
  86. Exec(hdbc, "create table test_odbc_batch_insert(id int primary key, col varchar2(50))");
  87. // 下面的代码根据用户输入的数据量,构造出将要入库的数据:
  88. {
  89. SQLRETURN retcode;
  90. SQLHSTMT hstmtinesrt = SQL_NULL_HSTMT;
  91. int i;
  92. SQLCHAR *sql = NULL;
  93. SQLINTEGER *ids = NULL;
  94. SQLCHAR *cols = NULL;
  95. SQLLEN *bufLenIds = NULL;
  96. SQLLEN *bufLenCols = NULL;
  97. SQLUSMALLINT *operptr = NULL;
  98. SQLUSMALLINT *statusptr = NULL;
  99. SQLULEN process = 0;
  100. // 这里是按列构造,每个字段的内存连续存放在一起。
  101. ids = (SQLINTEGER*)malloc(sizeof(ids[0]) * batchCount);
  102. cols = (SQLCHAR*)malloc(sizeof(cols[0]) * batchCount * 50);
  103. // 这里是每个字段中,每一行数据的内存长度。
  104. bufLenIds = (SQLLEN*)malloc(sizeof(bufLenIds[0]) * batchCount);
  105. bufLenCols = (SQLLEN*)malloc(sizeof(bufLenCols[0]) * batchCount);
  106. // 该行是否需要被处理,SQL_PARAM_IGNORE 或 SQL_PARAM_PROCEED
  107. operptr = (SQLUSMALLINT*)malloc(sizeof(operptr[0]) * batchCount);
  108. memset(operptr, 0, sizeof(operptr[0]) * batchCount);
  109. // 该行的处理结果。
  110. // 注:由于数据库中处理方式是同一语句隶属同一事务中,所以如果出错,那么待处理数据都将是出错的,并不会部分入库。
  111. statusptr = (SQLUSMALLINT*)malloc(sizeof(statusptr[0]) * batchCount);
  112. memset(statusptr, 88, sizeof(statusptr[0]) * batchCount);
  113. if (NULL == ids || NULL == cols || NULL == bufLenCols || NULL == bufLenIds)
  114. {
  115. fprintf(stderr, "FAILED:\tmalloc data memory failed\n");
  116. goto exit;
  117. }
  118. for (int i = 0; i < batchCount; i++)
  119. {
  120. ids[i] = i;
  121. sprintf(cols + 50 * i, "column test value %d", i);
  122. bufLenIds[i] = sizeof(ids[i]);
  123. bufLenCols[i] = strlen(cols + 50 * i);
  124. operptr[i] = (i < ignoreCount) ? SQL_PARAM_IGNORE : SQL_PARAM_PROCEED;
  125. }
  126. // Allocate Statement Handle
  127. retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmtinesrt);
  128. CHECK_ERROR(retcode, "SQLAllocHandle(SQL_HANDLE_STMT)",
  129. hstmtinesrt, SQL_HANDLE_STMT);
  130. // Prepare Statement
  131. sql = (SQLCHAR*)"insert into test_odbc_batch_insert values(?, ?)";
  132. retcode = SQLPrepare(hstmtinesrt, (SQLCHAR*) sql, SQL_NTS);
  133. sprintf((char*)loginfo, "SQLPrepare log: %s", (char*)sql);
  134. CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT);
  135. retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER)batchCount, sizeof(batchCount));
  136. CHECK_ERROR(retcode, "SQLSetStmtAttr", hstmtinesrt, SQL_HANDLE_STMT);
  137. retcode = SQLBindParameter(hstmtinesrt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(ids[0]), 0,&(ids[0]), 0, bufLenIds);
  138. CHECK_ERROR(retcode, "SQLBindParameter for id", hstmtinesrt, SQL_HANDLE_STMT);
  139. retcode = SQLBindParameter(hstmtinesrt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 50, 50, cols, 50, bufLenCols);
  140. CHECK_ERROR(retcode, "SQLBindParameter for cols", hstmtinesrt, SQL_HANDLE_STMT);
  141. retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAMS_PROCESSED_PTR, (SQLPOINTER)&process, sizeof(process));
  142. CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAMS_PROCESSED_PTR", hstmtinesrt, SQL_HANDLE_STMT);
  143. retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_STATUS_PTR, (SQLPOINTER)statusptr, sizeof(statusptr[0]) * batchCount);
  144. CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAM_STATUS_PTR", hstmtinesrt, SQL_HANDLE_STMT);
  145. retcode = SQLSetStmtAttr(hstmtinesrt, SQL_ATTR_PARAM_OPERATION_PTR, (SQLPOINTER)operptr, sizeof(operptr[0]) * batchCount);
  146. CHECK_ERROR(retcode, "SQLSetStmtAttr for SQL_ATTR_PARAM_OPERATION_PTR", hstmtinesrt, SQL_HANDLE_STMT);
  147. retcode = SQLExecute(hstmtinesrt);
  148. sprintf((char*)loginfo, "SQLExecute stmt log: %s", (char*)sql);
  149. CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT);
  150. retcode = SQLRowCount(hstmtinesrt, &rowsCount);
  151. CHECK_ERROR(retcode, "SQLRowCount execution", hstmtinesrt, SQL_HANDLE_STMT);
  152. if (rowsCount != (batchCount - ignoreCount))
  153. {
  154. sprintf(loginfo, "(batchCount - ignoreCount)(%d) != rowsCount(%d)", (batchCount - ignoreCount), rowsCount);
  155. CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
  156. }
  157. else
  158. {
  159. sprintf(loginfo, "(batchCount - ignoreCount)(%d) == rowsCount(%d)", (batchCount - ignoreCount), rowsCount);
  160. CHECK_ERROR(SQL_SUCCESS, loginfo, NULL, SQL_HANDLE_STMT);
  161. }
  162. // check row number returned
  163. if (rowsCount != process)
  164. {
  165. sprintf(loginfo, "process(%d) != rowsCount(%d)", process, rowsCount);
  166. CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
  167. }
  168. else
  169. {
  170. sprintf(loginfo, "process(%d) == rowsCount(%d)", process, rowsCount);
  171. CHECK_ERROR(SQL_SUCCESS, loginfo, NULL, SQL_HANDLE_STMT);
  172. }
  173. for (int i = 0; i < batchCount; i++)
  174. {
  175. if (i < ignoreCount)
  176. {
  177. if (statusptr[i] != SQL_PARAM_UNUSED)
  178. {
  179. sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_UNUSED", i, statusptr[i]);
  180. CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
  181. }
  182. }
  183. else if (statusptr[i] != SQL_PARAM_SUCCESS)
  184. {
  185. sprintf(loginfo, "statusptr[%d](%d) != SQL_PARAM_SUCCESS", i, statusptr[i]);
  186. CHECK_ERROR(SQL_ERROR, loginfo, NULL, SQL_HANDLE_STMT);
  187. }
  188. }
  189. retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmtinesrt);
  190. sprintf((char*)loginfo, "SQLFreeHandle hstmtinesrt");
  191. CHECK_ERROR(retcode, loginfo, hstmtinesrt, SQL_HANDLE_STMT);
  192. }
  193. exit:
  194. printf ("\nComplete.\n");
  195. // Connection
  196. if (hdbc != SQL_NULL_HDBC) {
  197. SQLDisconnect(hdbc);
  198. SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
  199. }
  200. // Environment
  201. if (henv != SQL_NULL_HENV)
  202. SQLFreeHandle(SQL_HANDLE_ENV, henv);
  203. return 0;
  204. }