📄 time_out.c
字号:
/* Program name : timeout.c** ** Description : This program handles timeout errors. It shows how a command** that has timed out can be cancelled and return results** from the next command on the same connection. It also ** shows how one connection can be marked dead as a result** of a timeout and still return results from another connect-** ion.**** Usage : Follow the instructions in the timeout.readme file to** create a timeout error. ** Run this program in another window - a timeout error will ** occur on the first command on the first connection. ** You will be prompted to cancel only the current command ** that caused a timeout and continue processing the following** commands on this connection as well as the next, or to** wait for another timeout period and see if the transaction** goes through to completion this time.**** Notes : This program uses the file 'timeout_handler.c' for the** error handling callback routines and contains specific** code to handle timeout errors.**** References : Open Client Client-Library/C Reference manual: refer to ** pages for ct_config, ct_cancel and the section on ** 'Connection Status' under Properties.***/#include <stdio.h>#include <ctpublic.h>#include "./example.h"/* Macro definitions for error handling */#define RETURN_IF(a,b) if (a != CS_SUCCEED)\ { fprintf(stderr, "Error in: %s\n", b); return a ;}#define EXIT_IF(a) if (a != CS_SUCCEED)\ {fprintf(stderr, "FATAL ERROR! Line %d\n", __LINE__);exit(-1);}/* Global definitions */#define MAX_COLSIZE 255;char rowbuffer[255][255];/* Function declarations */CS_RETCODE init_db PROTOTYPE(( CS_CONTEXT ** )); CS_RETCODE connect_db PROTOTYPE(( CS_CONTEXT *, CS_CONNECTION **, CS_CHAR *, CS_CHAR * ));CS_RETCODE cleanup_db PROTOTYPE(( CS_CONTEXT *, CS_RETCODE ));CS_RETCODE send_sql PROTOTYPE(( CS_COMMAND *, CS_CHAR * ));CS_RETCODE handle_returns PROTOTYPE(( CS_COMMAND * ));CS_RETCODE bind_columns PROTOTYPE(( CS_COMMAND * ));CS_RETCODE fetch_n_print PROTOTYPE(( CS_COMMAND * ));extern CS_RETCODE CS_PUBLIC ctlib_client_msg_handler PROTOTYPE(( CS_CONTEXT *, CS_CONNECTION *, CS_CLIENTMSG * ));extern CS_RETCODE CS_PUBLIC ctlib_server_msg_handler PROTOTYPE(( CS_CONTEXT *, CS_CONNECTION *, CS_SERVERMSG * ));int main(){ CS_CONTEXT *cntx_ptr; CS_CONNECTION *conn_ptr, *conn_ptr2; CS_COMMAND *cmd_ptr, *cmd_ptr2, *cmd_ptr3; CS_RETCODE ret; CS_INT time; /* Allocate context and initialize client-library */ ret = init_db(&cntx_ptr); EXIT_IF(ret); /* Establish connections to the server */ ret = connect_db(cntx_ptr, &conn_ptr, EX_USERNAME, EX_PASSWORD); EXIT_IF(ret); ret = connect_db(cntx_ptr, &conn_ptr2, EX_USERNAME, EX_PASSWORD); EXIT_IF(ret); /* Allocate command structures on connection 1 */ ret = ct_cmd_alloc(conn_ptr, &cmd_ptr); EXIT_IF(ret); ret = ct_cmd_alloc(conn_ptr, &cmd_ptr2); EXIT_IF(ret); /* Allocate a command structure on connection 2 */ ret = ct_cmd_alloc(conn_ptr2, &cmd_ptr3); EXIT_IF(ret); /* Set the timeout interval to 5 seconds. */ time = 5; ret= ct_config( cntx_ptr, CS_SET, CS_TIMEOUT, (CS_VOID *)&time, CS_UNUSED,NULL); EXIT_IF(ret); printf("Timeout value = %d seconds \n",time) ; /* send sql text to server */ printf("Executing Command 1 on connection 1.. \n"); ret = send_sql(cmd_ptr, "select * from pubs2.dbo.publishers"); /* process results */ ret = handle_returns(cmd_ptr); printf("Executing Command 2 on connection 1.. \n"); ret = send_sql(cmd_ptr2, "select name from pubs2.dbo.sysobjects where type = 'U'"); ret = handle_returns(cmd_ptr2); printf("Command 3 on connection 2.. \n"); ret = send_sql(cmd_ptr3, "select name from tempdb..sysobjects where type = 'U'"); ret = handle_returns(cmd_ptr3); /* Drop all the command structures */ ret = ct_cmd_drop( cmd_ptr ); EXIT_IF(ret); ret = ct_cmd_drop( cmd_ptr2 ); EXIT_IF(ret); ret = ct_cmd_drop( cmd_ptr3 ); EXIT_IF(ret); /* Close the connections to the server */ ret = ct_close(conn_ptr, CS_UNUSED); EXIT_IF(ret); ret = ct_close(conn_ptr2, CS_UNUSED); EXIT_IF(ret); /* Drop context and do general cleanup */ ret = cleanup_db(cntx_ptr, ret); EXIT_IF(ret); printf("End of program run!\n"); exit(0);}CS_RETCODEinit_db(cntx_ptr)CS_CONTEXT **cntx_ptr;{ CS_RETCODE retcode; /*initialize context handle*/ retcode = cs_ctx_alloc(CS_VERSION_100, cntx_ptr); RETURN_IF(retcode, "ct_ctx_alloc"); /*initialize the library*/ retcode = ct_init(*cntx_ptr, CS_VERSION_100); RETURN_IF(retcode, "ct_init"); return retcode;}CS_RETCODEcleanup_db(cntx_ptr, status)CS_CONTEXT *cntx_ptr;CS_RETCODE status;{ CS_RETCODE retcode; CS_INT exit_type; /* set exit_type to FORCE if bad retcode */ exit_type = (status != CS_SUCCEED) ? CS_FORCE_EXIT : CS_UNUSED; /* break the server connection */ retcode = ct_exit(cntx_ptr, exit_type); RETURN_IF(retcode, "db_cleanup:ct_exit"); /* free the context space */ retcode = cs_ctx_drop(cntx_ptr); RETURN_IF(retcode, "db_cleanup:cs_ctx_drop"); return retcode;}CS_RETCODEconnect_db(cntx_ptr, conn_ptr, user_name, password)CS_CONTEXT *cntx_ptr;CS_CONNECTION **conn_ptr;CS_CHAR *user_name;CS_CHAR *password;{ CS_RETCODE ret; /* allocate the connection and init conn_ptr */ ret = ct_con_alloc(cntx_ptr, conn_ptr); RETURN_IF(ret, "connect_db: ct_con_alloc"); /* set the user name and password properties */ ret = ct_con_props(*conn_ptr, CS_SET, CS_USERNAME, user_name, CS_NULLTERM, NULL); RETURN_IF(ret, "connect_db: ct_conprops USERNAME"); ret = ct_con_props(*conn_ptr, CS_SET, CS_PASSWORD, password, CS_NULLTERM, NULL); RETURN_IF(ret, "connect_db: ct_conprops PASSWORD"); ret = ct_callback ( NULL, *conn_ptr, CS_SET, CS_SERVERMSG_CB, (CS_VOID *)ctlib_server_msg_handler) ; RETURN_IF ( ret, "ct_callback "); ret = ct_callback ( NULL, *conn_ptr, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *)ctlib_client_msg_handler); RETURN_IF ( ret, "ct_callback: CLIENTMSG "); /* request connection to SQL Server */ ret = ct_connect(*conn_ptr, NULL, 0); RETURN_IF(ret, "connect_db: ct_connect"); return CS_SUCCEED;} CS_RETCODE send_sql(cmd_ptr, sqltext)CS_COMMAND *cmd_ptr;CS_CHAR *sqltext;{ CS_RETCODE ret; /* ** Indicate that we are sending T-SQL code ** and supply the code (as ascii string) */ ret = ct_command(cmd_ptr, CS_LANG_CMD, sqltext, CS_NULLTERM, CS_UNUSED); RETURN_IF(ret, "ct_command"); /* send the language packet to server */ ret = ct_send(cmd_ptr); RETURN_IF(ret, "ct_send"); return CS_SUCCEED;}CS_RETCODEhandle_returns(cmd_ptr)CS_COMMAND *cmd_ptr;{ CS_RETCODE result_ok; CS_INT result_type; /* ** Loop on a request to return result ** descriptions until no more are available */ while((result_ok = ct_results(cmd_ptr, &result_type)) == CS_SUCCEED) { /* ** All result types are handled in the ** same way, we want to indicate the ** order in which they are returned */ switch ((int)result_type) { case CS_ROW_RESULT: /* There are rows to process */ result_ok = bind_columns ( cmd_ptr ); RETURN_IF ( result_ok, "bind columns") ; result_ok = fetch_n_print ( cmd_ptr ); RETURN_IF ( result_ok, "fetch_n_print"); break; case CS_CMD_SUCCEED: /* ** A select command succeeded ** which returns no rows. */ break; case CS_CMD_DONE: /* ** Done with one result set. ** Go on to the next. */ break; case CS_CMD_FAIL: /* ** The server encountered an error ** while processing the command. */ fprintf(stdout, "TYPE: CMD_FAIL\n"); break; case CS_STATUS_RESULT: /* ** Return status. */ fprintf(stdout, "TYPE: STATUS_RESULT\n"); break; default: /* ** We got something unexpected. */ fprintf(stdout, "TYPE: UNKNOWN\n"); RETURN_IF(CS_FAIL, "handle_returns: bad result type\n"); break; }/* end result type switch */ }/* end while results pending */ /* normal termination of loop */ if (result_ok == CS_END_RESULTS ) { return(CS_SUCCEED); } if (result_ok == CS_FAIL ) printf("\n ct_result returned: CS_FAIL \n"); return CS_FAIL;}CS_RETCODE bind_columns (cmd_ptr )CS_COMMAND *cmd_ptr ;{ CS_RETCODE retcode ; CS_INT i , num_cols ; CS_DATAFMT target_format ; retcode = ct_res_info ( cmd_ptr, CS_NUMDATA, &num_cols, CS_UNUSED, NULL) ; RETURN_IF ( retcode, "ct_bind : ct_res_info "); for ( i = 1 ; i <= num_cols ; i++ ) { memset ( &target_format, 0, CS_SIZEOF(target_format)) ; target_format.datatype = CS_CHAR_TYPE ; target_format.maxlength = MAX_COLSIZE ; target_format.count = 1 ; target_format.format = CS_FMT_NULLTERM ; retcode = ct_bind ( cmd_ptr, i, &target_format, rowbuffer[i-1], NULL,NULL); RETURN_IF ( retcode, "bind_columns: ct_bind "); } return CS_SUCCEED ;} CS_RETCODE fetch_n_print ( cmd_ptr )CS_COMMAND *cmd_ptr ;{ CS_RETCODE retcode ; CS_INT i, num_cols ; retcode = ct_res_info ( cmd_ptr, CS_NUMDATA, &num_cols, CS_UNUSED, NULL ); RETURN_IF ( retcode, "fetch_n_print: ct_res_info "); while (( (retcode = ct_fetch(cmd_ptr, CS_UNUSED, CS_UNUSED, CS_UNUSED, (CS_INT *)NULL)) == CS_SUCCEED ) || ( retcode == CS_ROW_FAIL )) { if ( retcode == CS_ROW_FAIL ) { printf("ct_fetch returned row fail \n"); continue ; } for ( i = 1 ; i <= num_cols ; i++ ) { printf(" %s \t ", rowbuffer[i-1] ); } printf("\n"); } if ( retcode != CS_END_DATA) RETURN_IF ( retcode, "fetch_n_print ") ; return CS_SUCCEED ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -