proc.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /***************************************************************************
  2. * Licensed Materials - Property of IBM and/or HCL
  3. *
  4. * IBM Informix Client-SDK
  5. *
  6. * (C) Copyright IBM Corporation 1997, 2004 All rights reserved.
  7. * (c) Copyright HCL Technologies Ltd. 2017. All Rights Reserved.
  8. *
  9. *
  10. *
  11. *
  12. *
  13. * Title: proc.c
  14. *
  15. * Description: To execute a stored procedure returning multiple results
  16. *
  17. * The stored procedure executed is -
  18. * PROCEDURE multiReturnProc (i integer)
  19. * RETURNING integer;
  20. * define j integer;
  21. * for j in (1 to 5)
  22. * return i*j with resume;
  23. * end for;
  24. * END PROCEDURE
  25. *
  26. * Because the Informix ODBC driver version 3.3 does not
  27. * yet suport output parameters for stored procedures,
  28. * the way to get return values from a procedure is to
  29. * use SQLBindCol and SQLFetch. This works whether the
  30. * procedure returns a single value or multiple values.
  31. *
  32. *
  33. ***************************************************************************
  34. */
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <string.h>
  38. #ifndef NO_WIN32
  39. #include <io.h>
  40. #include <windows.h>
  41. #include <conio.h>
  42. #endif /*NO_WIN32*/
  43. #include "infxcli.h"
  44. #define ERRMSG_LEN 200
  45. SQLCHAR defDsn[] = "odbc_demo";
  46. SQLINTEGER checkError (SQLRETURN rc,
  47. SQLSMALLINT handleType,
  48. SQLHANDLE handle,
  49. SQLCHAR* errmsg)
  50. {
  51. SQLRETURN retcode = SQL_SUCCESS;
  52. SQLSMALLINT errNum = 1;
  53. SQLCHAR sqlState[6];
  54. SQLINTEGER nativeError;
  55. SQLCHAR errMsg[ERRMSG_LEN];
  56. SQLSMALLINT textLengthPtr;
  57. if ((rc != SQL_SUCCESS) && (rc != SQL_SUCCESS_WITH_INFO))
  58. {
  59. while (retcode != SQL_NO_DATA)
  60. {
  61. retcode = SQLGetDiagRec (handleType, handle, errNum, sqlState, &nativeError, errMsg, ERRMSG_LEN, &textLengthPtr);
  62. if (retcode == SQL_INVALID_HANDLE)
  63. {
  64. fprintf (stderr, "checkError function was called with an invalid handle!!\n");
  65. return 1;
  66. }
  67. if ((retcode == SQL_SUCCESS) || (retcode == SQL_SUCCESS_WITH_INFO))
  68. fprintf (stderr, "ERROR: %d: %s : %s \n", nativeError, sqlState, errMsg);
  69. errNum++;
  70. }
  71. fprintf (stderr, "%s\n", errmsg);
  72. return 1; /* all errors on this handle have been reported */
  73. }
  74. else
  75. return 0; /* no errors to report */
  76. }
  77. int main (long argc,
  78. char* argv[])
  79. {
  80. /* Declare variables
  81. */
  82. /* Handles */
  83. SQLHDBC hdbc;
  84. SQLHENV henv;
  85. SQLHSTMT hstmt;
  86. /* Miscellaneous variables */
  87. SQLCHAR dsn[20]; /*name of the DSN used for connecting to the database*/
  88. SQLRETURN rc = 0;
  89. SQLINTEGER in;
  90. SQLCHAR* createProcStmt = (SQLCHAR *) "CREATE PROCEDURE multiReturnProc (i integer)\
  91. RETURNING integer;\
  92. define j integer;\
  93. for j in (1 to 5)\
  94. return i*j with resume;\
  95. end for;\
  96. END PROCEDURE;";
  97. SQLCHAR* dropProcStmt = (SQLCHAR *) "DROP PROCEDURE multiReturnProc";
  98. SQLSMALLINT inputParam = 2;
  99. SQLINTEGER retVal = 7, cbRetVal = 0, cbInputParam = 0;
  100. /* STEP 1. Get data source name from command line (or use default)
  101. ** Allocate the environment handle and set ODBC version
  102. ** Allocate the connection handle
  103. ** Establish the database connection
  104. ** Allocate the statement handle
  105. */
  106. /* If(dsn is not explicitly passed in as arg) */
  107. if (argc != 2)
  108. {
  109. /* Use default dsn - odbc_demo */
  110. fprintf (stdout, "\nUsing default DSN : %s\n", defDsn);
  111. strcpy ((char *)dsn, (char *)defDsn);
  112. }
  113. else
  114. {
  115. /* Use specified dsn */
  116. strcpy ((char *)dsn, (char *)argv[1]);
  117. fprintf (stdout, "\nUsing specified DSN : %s\n", dsn);
  118. }
  119. /* Allocate the Environment handle */
  120. rc = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
  121. if (rc != SQL_SUCCESS)
  122. {
  123. fprintf (stdout, "Environment Handle Allocation failed\nExiting!!");
  124. return (1);
  125. }
  126. /* Set the ODBC version to 3.0 */
  127. rc = SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, 0);
  128. if (checkError (rc, SQL_HANDLE_ENV, henv, (SQLCHAR *) "Error in Step 1 -- SQLSetEnvAttr failed\nExiting!!"))
  129. return (1);
  130. /* Allocate the connection handle */
  131. rc = SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc);
  132. if (checkError (rc, SQL_HANDLE_ENV, henv, (SQLCHAR *) "Error in Step 1 -- Connection Handle Allocation failed\nExiting!!"))
  133. return (1);
  134. /* Establish the database connection */
  135. rc = SQLConnect (hdbc, dsn, SQL_NTS, (SQLCHAR *) "", SQL_NTS, (SQLCHAR *) "", SQL_NTS);
  136. if (checkError (rc, SQL_HANDLE_DBC, hdbc, (SQLCHAR *) "Error in Step 1 -- SQLConnect failed\nExiting!!"))
  137. return (1);
  138. /* Allocate the statement handle */
  139. rc = SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt );
  140. if (checkError (rc, SQL_HANDLE_DBC, hdbc, (SQLCHAR *) "Error in Step 1 -- Statement Handle Allocation failed\nExiting!!"))
  141. return (1);
  142. fprintf (stdout, "STEP 1 done...connected to database\n");
  143. /* STEP 2. Create the stored procedure in the database
  144. */
  145. /* Execute the SQL statement to create the stored procedure*/
  146. rc = SQLExecDirect (hstmt, createProcStmt, SQL_NTS);
  147. if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "Error in Step 2 -- SQLExecDirect failed\n"))
  148. goto Exit;
  149. fprintf (stdout, "STEP 2 done...stored procedure created\nExecuting procedure...\n\n");
  150. /* STEP 3. Bind the input parameter
  151. ** Execute the procedure
  152. ** Bind the result set column (return values)
  153. ** Fetch the results
  154. ** Display the results
  155. ** Close the result set cursor
  156. */
  157. /* Bind the input parameter */
  158. rc = SQLBindParameter (hstmt, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &inputParam, 0, &cbInputParam);
  159. if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "Error in Step 3 -- SQLBindParameter failed\n"))
  160. return (1);
  161. /* Execute the procedure */
  162. rc = SQLExecDirect (hstmt, (SQLCHAR *) "{call multiReturnProc (?)}", SQL_NTS);
  163. if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "Error in Step 3 -- SQLExecDirect failed\n"))
  164. goto Exit;
  165. /* Bind the result set column */
  166. rc = SQLBindCol (hstmt, 1, SQL_C_SLONG, (SQLPOINTER)&retVal, 0, &cbRetVal);
  167. if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "Error in Step 3 -- SQLBindCol failed\n"))
  168. goto Exit;
  169. /* Fetch and display the results */
  170. while (1)
  171. {
  172. rc = SQLFetch (hstmt);
  173. if (rc == SQL_NO_DATA_FOUND)
  174. break;
  175. else if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "Error in Step 3 -- SQLFetch failed\n"))
  176. goto Exit;
  177. /* Display the results */
  178. fprintf (stdout, "Procedure returned %d\n", retVal);
  179. }
  180. /* Close the result set cursor */
  181. rc = SQLCloseCursor (hstmt);
  182. if (checkError (rc, SQL_HANDLE_STMT, hstmt, (SQLCHAR *) "Error in Step 3 -- SQLCloseCursor failed\n"))
  183. goto Exit;
  184. fprintf (stdout, "\nSTEP 3 done...stored procedure executed\n");
  185. Exit:
  186. /* CLEANUP: Drop the stored procedure from the database
  187. ** Close the statement handle
  188. ** Free the statement handle
  189. ** Disconnect from the datasource
  190. ** Free the connection and environment handles
  191. ** Exit
  192. */
  193. /* Drop the stored procedure from the database */
  194. SQLExecDirect (hstmt, dropProcStmt, SQL_NTS);
  195. /* Close the statement handle */
  196. SQLFreeStmt (hstmt, SQL_CLOSE);
  197. /* Free the statement handle */
  198. SQLFreeHandle (SQL_HANDLE_STMT, hstmt);
  199. /* Disconnect from the data source */
  200. SQLDisconnect (hdbc);
  201. /* Free the environment handle and the database connection handle */
  202. SQLFreeHandle (SQL_HANDLE_DBC, hdbc);
  203. SQLFreeHandle (SQL_HANDLE_ENV, henv);
  204. fprintf (stdout,"\n\nHit <Enter> to terminate the program...\n\n");
  205. in = getchar ();
  206. return (rc);
  207. }