📄 array_bind.c
字号:
/* Program name : array_bind.c** ** Description : This program makes use of bulk library calls to bulk copy** variable and fixed length data using array binding. ** Array binding variable length data is different from ** handling fixed length data. Please read the sections in the** 'References' below for a detailed explanation.** Array binding helps improve performance.**** Script file : Execute script array_bind.sql prior to executing the program.** ** Note : This program requires bulk-library 11.x and up, as it makes ** use of a new api call 'blk_rowxfer_mult' available only in** this release.**** References : Open Client/Open Server Common Libraries reference manual.** Refer to the sections on 'blk_rowxfer_mult' and 'Array Binding'.***/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctpublic.h>#include <bkpublic.h>#include <example.h>/* Macros for error handling */#define RETURN_IF(a,b) if (a != CS_SUCCEED) {fprintf(stdout,"Error - %s\n",b); return a;} #define EXIT_IF(a) if (a != CS_SUCCEED) {fprintf(stdout,"FATAL error on line %d "); exit(-1);}#define BULK_SIZE 5 /* size for array binding. */#define MAX_COLUMN 10 /* used by 'rowbuffer' */#define MAX_COLSIZE 255 /* used by 'rowbuffer' *//* Global definitions */typedef struct /* Data structure for this bcp operation */{ CS_INT emp_id[5]; CS_CHAR name[5][10];} BCP_DATA ;/* Store the bcp data in an array */BCP_DATA databuf[]={ 1001,1002,1003,1004,1005, "Sandy", "Mary", "Joe", "Smith", "Jill"};/* Buffer to hold result data */char rowbuffer[MAX_COLUMN][MAX_COLSIZE] ;CS_STATIC CS_RETCODE init_db PROTOTYPE(( CS_CONTEXT ** )); CS_STATIC CS_RETCODE connect_db PROTOTYPE(( CS_CONTEXT *, CS_CONNECTION **, CS_CHAR *, CS_CHAR * ));CS_STATIC CS_RETCODE cleanup_db PROTOTYPE(( CS_CONTEXT *, CS_RETCODE ));CS_STATIC CS_RETCODE send_sql PROTOTYPE(( CS_COMMAND *, CS_CHAR * ));CS_STATIC CS_RETCODE handle_returns PROTOTYPE(( CS_COMMAND * ));CS_STATIC CS_RETCODE bind_columns PROTOTYPE(( CS_COMMAND * ));CS_STATIC 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 * ));CS_STATIC CS_RETCODE write_to_table PROTOTYPE (( CS_CONNECTION *, CS_INT ));int main(){ CS_CONTEXT *cntx_ptr ; CS_CONNECTION *conn_ptr ; CS_COMMAND *cmd_ptr ; CS_RETCODE ret ; /* Initialize a context */ ret = init_db(&cntx_ptr); EXIT_IF(ret); /* Routine to make a connection to the server */ ret = connect_db (cntx_ptr, &conn_ptr, EX_USERNAME, EX_PASSWORD); EXIT_IF(ret); /* Allocate a command structure */ ret = ct_cmd_alloc (conn_ptr, &cmd_ptr ); EXIT_IF(ret); /* Send a command to set the database context */ ret = send_sql (cmd_ptr, "use tempdb"); EXIT_IF(ret); /* handle results from the current command */ ret = handle_returns ( cmd_ptr ); EXIT_IF(ret); /* Perform bulk copy operations */ ret = write_to_table(conn_ptr, BULK_SIZE); EXIT_IF(ret); /* Now select the data back from the table, so we can see what we inserted. */ ret = send_sql (cmd_ptr, "select * from test_bcp "); EXIT_IF(ret); /* handle results from the current command */ ret = handle_returns ( cmd_ptr ); EXIT_IF(ret); /* Drop the command structure */ ret = ct_cmd_drop(cmd_ptr); EXIT_IF(ret); /* Close the connection to the server */ ret = ct_close ( conn_ptr, CS_UNUSED ) ; EXIT_IF(ret); /* Clean up the context */ ret = cleanup_db (cntx_ptr, ret ); EXIT_IF ( ret ); printf("\n End of bulkcopy program. \n"); exit(0);}CS_RETCODEwrite_to_table(connection, bind_count)CS_CONNECTION *connection; CS_INT bind_count; /* array bind size */{ CS_RETCODE retcode; CS_INT i, numrows, len = 4; CS_BLKDESC *blkdesc; CS_DATAFMT datafmt_int, datafmt_char ; CS_INT datalen[5], datalen2[5]; BCP_DATA *buffer ; /* get the bulk copy descriptor */ retcode = blk_alloc(connection, BLK_VERSION_110, &blkdesc); RETURN_IF ( retcode, "blk_alloc"); /* define table to do the bulk copy */ retcode = blk_init(blkdesc, CS_BLK_IN, "test_bcp", strlen("test_bcp")); RETURN_IF ( retcode, "blk_init"); /* Initialize and describe the data format structure */ memset(&datafmt_int, 0 , sizeof(CS_DATAFMT)); datafmt_int.count = bind_count; datafmt_int.datatype = CS_INT_TYPE; datafmt_int.format = CS_FMT_UNUSED; datafmt_int.maxlength = sizeof(CS_INT); /* Define the datalength of the first columns' values */ for ( i = 0 ; i < 5; i++) datalen[i] = sizeof(CS_INT); /* bind the variables to the columns and transfer the data */ buffer = databuf ; retcode = blk_bind(blkdesc, 1, &datafmt_int, buffer->emp_id, datalen, NULL); RETURN_IF ( retcode, "blk bind 1 ( emp_id ) "); /* Initialize and describe the data format structure for the second column of type 'char'. It is recommended that different data format structures be used for different datatypes. */ memset(&datafmt_char, 0 , sizeof(CS_DATAFMT)); datafmt_char.count = bind_count; datafmt_char.datatype = CS_CHAR_TYPE; datafmt_char.format = CS_BLK_ARRAY_MAXLEN; datafmt_char.maxlength = 10; /* Since we have variable length data, specify the length of ** each data value. */ for ( i = 0 ; i < 5; i++ ) datalen2[i] = strlen(buffer->name[i]); retcode = blk_bind(blkdesc, 2, &datafmt_char, buffer->name, datalen2, NULL); RETURN_IF ( retcode, "blk bind 2 ( name ) "); /* transfer the rows to be copied to the server */ retcode = blk_rowxfer_mult(blkdesc, &bind_count); RETURN_IF ( retcode, "bulk transfer "); /* Commit transactions to the database */ retcode = blk_done(blkdesc, CS_BLK_ALL, &numrows); RETURN_IF ( retcode, "bulk done "); printf("Bulk copied %d rows successfully. \n", numrows); /* Drop the bulk descriptor */ retcode = blk_drop(blkdesc); RETURN_IF ( retcode, "bulk drop "); return CS_SUCCEED;}CS_RETCODE init_db (cntx_ptr)CS_CONTEXT **cntx_ptr ;{ CS_RETCODE retcode ; retcode = cs_ctx_alloc (CS_VERSION_100,cntx_ptr ); RETURN_IF ( retcode, "cs_ctx_alloc "); retcode = ct_init (*cntx_ptr, CS_VERSION_100 ); RETURN_IF ( retcode, "ct_init "); retcode = ct_callback ( *cntx_ptr, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *)ctlib_server_msg_handler) ; RETURN_IF ( retcode, "ct_callback "); retcode = ct_callback (*cntx_ptr, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *)ctlib_client_msg_handler); RETURN_IF ( retcode, "ct_callback: CLIENTMSG "); return retcode ;}CS_RETCODE cleanup_db ( cntx_ptr, status )CS_CONTEXT *cntx_ptr ;CS_RETCODE status ;{ CS_RETCODE retcode ; CS_INT exit_type ; exit_type = ( status != CS_SUCCEED ) ? CS_FORCE_EXIT : CS_UNUSED ; retcode = ct_exit (cntx_ptr, exit_type ); RETURN_IF ( retcode, "db_cleanup:ct_exit "); retcode = cs_ctx_drop (cntx_ptr) ; RETURN_IF ( retcode, "db_cleanup:cs_drop "); return retcode ; } CS_RETCODE connect_db (cntx_ptr, conn_ptr, user_name, password )CS_CONTEXT *cntx_ptr ;CS_CONNECTION **conn_ptr ;CS_CHAR *user_name, *password ;{ CS_RETCODE retcode ; CS_BOOL bool; retcode = ct_con_alloc (cntx_ptr, conn_ptr ); RETURN_IF ( retcode, "connect_db: ct_con_alloc "); retcode = ct_con_props ( *conn_ptr, CS_SET, CS_USERNAME, user_name, CS_NULLTERM, NULL ); RETURN_IF ( retcode, "connect_db: ct_con_props: username "); retcode = ct_con_props ( *conn_ptr, CS_SET, CS_PASSWORD, password, CS_NULLTERM, NULL ); RETURN_IF ( retcode, "connect_db: ct_con_props: password"); /* enable bulk login property */ bool = CS_TRUE; retcode = ct_con_props( *conn_ptr, CS_SET, CS_BULK_LOGIN, &bool, CS_UNUSED, NULL); RETURN_IF ( retcode, "connect_db: ct_con_props: bulk login"); retcode = ct_connect ( *conn_ptr, NULL, 0 ) ; RETURN_IF ( retcode, "connect_db: ct_connect ") ; return CS_SUCCEED ;}CS_RETCODE send_sql (cmd_ptr, sqltext)CS_COMMAND *cmd_ptr ;CS_CHAR sqltext[30];{ CS_RETCODE retcode ; CS_DATAFMT datafmt ; printf("sql = %s\n",sqltext); retcode = ct_command ( cmd_ptr, CS_LANG_CMD, sqltext, CS_NULLTERM, CS_UNUSED ); RETURN_IF ( retcode, "ct_command "); retcode = ct_send ( cmd_ptr ); RETURN_IF ( retcode, "ct_send "); return CS_SUCCEED ;}CS_RETCODE handle_returns ( cmd_ptr )CS_COMMAND *cmd_ptr ;{ CS_RETCODE results_ok ; CS_INT result_type; CS_DATAFMT target_format; while (( results_ok = ct_results ( cmd_ptr, &result_type)) == CS_SUCCEED ) { switch ((int)result_type) { case CS_ROW_RESULT: printf("TYPE: ROW RESULT \n"); results_ok = bind_columns ( cmd_ptr ); RETURN_IF ( results_ok, "bind columns"); results_ok = fetch_n_print ( cmd_ptr ); RETURN_IF ( results_ok, "fetch_n_print"); break ; case CS_CMD_SUCCEED: printf("TYPE: CMD SUCCEEDED \n"); break ; case CS_CMD_DONE : printf("TYPE : CMD DONE \n"); break ; case CS_CMD_FAIL : printf("TYPE: CMD FAIL \n"); break ; default : RETURN_IF ( CS_FAIL, "unknown results \n"); break ; } ; } if ( results_ok == CS_END_RESULTS ) return CS_SUCCEED ; 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 = 255 ; target_format.count = 1 ; target_format.format = CS_FMT_NULLTERM; target_format.locale = NULL; 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 + -