db2.c
上传用户:xfwatch
上传日期:2020-12-14
资源大小:872k
文件大小:7k
源码类别:

中间件编程

开发平台:

Java

  1. #include <stdio.h>
  2. #include <string.h>
  3. #ifdef DB2
  4. #include <sqlcli.h>
  5. #include "xa.h"
  6.  
  7. #include "tx/request.h"
  8. #ifdef DECLSPEC_DEFN
  9. extern __declspec(dllimport) struct xa_switch_t db2xa_switch_std;
  10. extern __declspec(dllimport) struct xa_switch_t * SQL_API_FN db2xacic_std();
  11. #else
  12. #define db2xa_switch_std (*db2xa_switch_std)
  13. extern struct xa_switch_t db2xa_switch_std;
  14. struct xa_switch_t * SQL_API_FN db2xacic_std();
  15. #endif
  16. static SQLCHAR CTSQL[] = "CREATE TABLE XEMP (EMPNO integer NOT NULL PRIMARY KEY, ENAME varchar(32))";
  17. /*static SQLCHAR DTSQL[] = "DROP TABLE XEMP";*/
  18. static SQLCHAR ISQL[] = "INSERT INTO XEMP VALUES (?, 'Jim')";
  19. static SQLCHAR USQL[] = "UPDATE XEMP SET ENAME='NEW_NAME' WHERE EMPNO=?";
  20. static SQLCHAR DSQL[] = "DELETE FROM XEMP WHERE EMPNO >= ?";
  21. static SQLCHAR SSQL[] = "select EMPNO, ENAME from XEMP WHERE EMPNO >= ?";
  22. static SQLRETURN check_error(SQLSMALLINT, SQLHANDLE, SQLRETURN, const char*, SQLCHAR*);
  23. #define CHECK_HANDLE( htype, hndl, rc, msg, sql ) 
  24.    if (rc != SQL_SUCCESS) {return check_error(htype,hndl,rc,msg,sql);}
  25. long db2_xaflags()
  26. {
  27. struct xa_switch_t *xasw = db2xacic_std();
  28. return xasw->flags; //db2xa_switch_std.flags;
  29. }
  30. /* can't get SQLBindParameter to work - use string substitution for the time being */
  31. static const char *strsub(const char *src, char *dest, size_t sz, const char *match, char *rep)
  32. {
  33. char *s;
  34. size_t len;
  35. if ((s = strstr(src, match)) == NULL)
  36. return NULL;
  37. len = s - src;  /* length of the string upto the match */
  38. strncpy(dest, src, len);
  39. sprintf(dest+len, "%s%s", rep, s + strlen(match));
  40. return dest;
  41. }
  42. static SQLRETURN doSelect(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT shdl, SQLCHAR sql[], int *rcnt)
  43. {
  44. SQLCHAR name[33];
  45. SQLINTEGER empno, col2sz, col1sz;
  46. SQLRETURN rc = SQLExecDirect(shdl, sql, SQL_NTS);
  47. CHECK_HANDLE(SQL_HANDLE_STMT, shdl, rc, "SQLExecDirect", sql);
  48.  
  49. /* bind empno and name to columns 1 and 2 of the fetch */
  50. SQLBindCol(shdl, 1, SQL_C_LONG, (SQLPOINTER) &empno, (SQLINTEGER) sizeof (SQLINTEGER), (SQLINTEGER *) &col1sz);
  51. SQLBindCol(shdl, 2, SQL_C_CHAR, (SQLPOINTER) name, (SQLINTEGER) sizeof (name), &col2sz);
  52.  
  53. *rcnt = 0;
  54. while (SQLFetch(shdl) == SQL_SUCCESS) {
  55. *rcnt += 1;
  56. /* userlogc_debug("(%ld,%s)n", empno, name);*/
  57. }
  58. return SQL_SUCCESS;
  59. }
  60. static SQLRETURN doSql(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT shdl, SQLCHAR sql[])
  61. {
  62. SQLRETURN rc;
  63. userlogc_debug("doSql %sn", sql);
  64. rc = SQLPrepare(shdl, sql, SQL_NTS);
  65. CHECK_HANDLE(SQL_HANDLE_STMT, shdl, rc, "SQLPrepare", sql);
  66. SQLExecDirect(shdl, sql, SQL_NTS);
  67. CHECK_HANDLE(SQL_HANDLE_STMT, shdl, rc, "SQLExecDirect", sql);
  68. return SQL_SUCCESS;
  69. }
  70. static SQLRETURN fini(SQLHENV henv, SQLHDBC hdbc)
  71. {
  72. /* clean up - free the connection and environment handles */
  73. SQLDisconnect(hdbc);
  74. SQLFreeConnect(hdbc);
  75. SQLFreeEnv(henv);
  76. return SQL_SUCCESS;
  77. }
  78. static SQLRETURN init(char *dbalias, SQLHENV *henv, SQLHDBC *hdbc)
  79. {
  80. SQLHSTMT hstmt; /* statement handle */
  81. SQLRETURN rc;
  82. *henv = 0;
  83. rc = SQLAllocEnv(henv);
  84. CHECK_HANDLE(SQL_HANDLE_ENV, *henv, rc, "SQLAllocEnv", (SQLCHAR *) "");
  85. rc = SQLAllocConnect(*henv, hdbc);
  86. CHECK_HANDLE(SQL_HANDLE_DBC, *hdbc, rc, "SQLAllocConnect", (SQLCHAR *) "");
  87. rc = SQLConnect(*hdbc, (SQLCHAR *) dbalias, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS);
  88. CHECK_HANDLE(SQL_HANDLE_DBC, *hdbc, rc, "SQLConnect", (SQLCHAR *) "");
  89. rc = SQLAllocHandle(SQL_HANDLE_STMT, *hdbc, &hstmt);
  90. CHECK_HANDLE(SQL_HANDLE_STMT, hstmt, rc, "SQLAllocHandle", (SQLCHAR *) "");
  91. (void) SQLExecDirect(hstmt, CTSQL, SQL_NTS);
  92. /*CHECK_HANDLE(SQL_HANDLE_STMT, hstmt, rc, "SQLExecDirect", CTSQL);*/
  93. (void) SQLFreeStmt(hstmt, SQL_DROP);
  94. return rc;
  95. }
  96. static SQLRETURN doWork(char op, char *arg, SQLHENV henv, SQLHDBC hdbc, SQLHSTMT shdl, test_req_t *resp) 
  97. {
  98. SQLRETURN status = SQL_ERROR;
  99. int empno = (*arg ? atoi(arg) : 8000);
  100. char buf1[512];
  101. char buf2[512];
  102. int rcnt = 0;   // no of matching records
  103. sprintf(buf2, "%d", empno);
  104. (resp->data)[0] = 0;
  105. if (op == '0') {
  106. (void) strsub((const char*) ISQL, buf1, sizeof (buf1), "?", buf2);
  107. status = doSql(henv, hdbc, shdl, (SQLCHAR *) buf1);
  108. } else if (op == '1') {
  109. (void) strsub((const char*) SSQL, buf1, sizeof (buf1), "?", buf2);
  110. status = doSelect(henv, hdbc, shdl, (SQLCHAR *) buf1, &rcnt);
  111. userlogc_snprintf(resp->data, sizeof (resp->data), "%d", rcnt);
  112. } else if (op == '2') {
  113. (void) strsub((const char*) USQL, buf1, sizeof (buf1), "?", buf2);
  114. status = doSql(henv, hdbc, shdl, (SQLCHAR *) buf1);
  115. } else if (op == '3') {
  116. (void) strsub((const char*) DSQL, buf1, sizeof (buf1), "?", buf2);
  117. status = doSql(henv, hdbc, shdl, (SQLCHAR *) buf1);
  118. }
  119. return status;
  120. }
  121. int db2_access(test_req_t *req, test_req_t *resp)
  122. {
  123. SQLHENV henv; /* environment handle */
  124. SQLHDBC hdbc; /* connection handle */
  125. SQLRETURN rc = SQL_ERROR;
  126. SQLHSTMT shdl;
  127. userlogc_debug("op=%c data=%s db=%sn", req->op, req->data, req->db);
  128. if (init(req->db, &henv, &hdbc) != SQL_SUCCESS)
  129. return (int) rc;
  130. rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &shdl);
  131. if ( rc != SQL_SUCCESS ) {
  132. (void) check_error(SQL_HANDLE_STMT, shdl, rc, "SQLAllocHandle", (SQLCHAR *) "statement handle");
  133. } else {
  134. rc = doWork(req->op, req->data, henv, hdbc, shdl, resp);
  135. (void) SQLFreeStmt(shdl, SQL_DROP);
  136. }
  137. fini(henv, hdbc);
  138. return (int) rc;
  139. }
  140. /**
  141.  * print diagnostics in case of error:
  142.  * convert error code from last CLI invokation to a string
  143.  * and use SQLGetDiagRec() to display the SQLSTATE and message
  144.  * for the given handle type
  145.  */
  146. static SQLRETURN check_error( SQLSMALLINT htype, /* A handle type */
  147.    SQLHANDLE   hndl,  /* A handle */
  148.    SQLRETURN   rc,   /* Return code */
  149.    const char* msg,   /* prefix message */
  150.    SQLCHAR* sql)   /* the sql for statement handles */
  151. {
  152. SQLCHAR  buffer[SQL_MAX_MESSAGE_LENGTH + 1] ;
  153. SQLCHAR  sqlstate[SQL_SQLSTATE_SIZE + 1] ;
  154. SQLINTEGER  sqlcode ;
  155. SQLSMALLINT length, i = 1;
  156. switch (rc) {
  157. case SQL_SUCCESS: /* 0 */
  158. return rc;
  159. case SQL_SUCCESS_WITH_INFO: /* 1 */
  160. userlogc_warn("%s error:  SQL_SUCCESS_WITH_INFO: ...", msg);
  161. break;
  162. case SQL_NO_DATA_FOUND: /* 100 */
  163. userlogc_warn("%s error: SQL_NO_DATA_FOUND: ...", msg);
  164. break;
  165. case SQL_ERROR: /* -1 */
  166. userlogc_warn("%s error: SQL_ERROR: ...", msg);
  167. break;
  168. case SQL_INVALID_HANDLE: /* -2 */
  169. userlogc_warn("%s error: SQL_INVALID HANDLE: ...", msg);
  170. break;
  171. default:
  172. /* SQL_NEED_DATA, SQL_NO_DATA, SQL_STILL_EXECUTING */
  173. userlogc_warn("%s error: code=%d: ...", msg, rc);
  174. break;
  175. }
  176. /*
  177.  * use SQLGetDiagRec() to display SQLSTATE and message for the given handle type
  178.  */
  179. while (SQLGetDiagRec(htype, hndl, i++, sqlstate, &sqlcode, buffer,
  180. SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS ) {
  181.    userlogc_warn( "t*** SQLSTATE: %s", sqlstate) ;
  182.    userlogc_warn( "t*** Native Error Code: %ld", sqlcode) ;
  183.    userlogc_warn( "t*** buffer: %s", buffer) ;
  184. }
  185. return rc;
  186. }
  187. #endif