www.pudn.com > dynamicsql.rar > TestAllMethods.pc


/*********************************************************** 
 * TestAllMethods.pc 
 * created by Caoqing on 2003.12.24 
 * 
 * This project is used to realize dynamic sql statments used     
 * four methods. 
 *   
 *   
 * 
 ************************************************************/ 
 
#include  
#include  
#include  
#include  
 
#include  
#include  
#include  
 
EXEC SQL INCLUDE sqlca; 
EXEC SQL INCLUDE sqlda;  
 
#define MAX_SELECT_ITEMS 40 
#define MAX_VNAME_LEN 64 
#define MAX_INAME_LEN 64 
 
typedef struct 
{ 
	int precision; 
	int scale; 
}SELDA_LEN; 
 
jmp_buf restore_err; 
 
void testMethod1(); 
void testMethod2(); 
void testMethod3(); 
void testMethod4(); 
void AllocateDescriptors(SQLDA * sel_desc, SQLDA * bind_desc, int maxsize); 
void UnAllocateDescriptors(SQLDA * sel_desc, SQLDA * bind_desc, int maxsize); 
short getInputStmt(char * stmtarr); 
void errorProc(); 
void QueryProcess(SQLDA * sel_desc, SQLDA * bind_desc); 
 
main() 
{ 
EXEC SQL BEGIN DECLARE SECTION; 
	char username[15] = "schoolfee"; 
	char passwd[15] = "school"; 
	char dbstring[25] = "syntong";	 
EXEC SQL END DECLARE SECTION; 
 
	/* Connect database. */ 
	EXEC SQL WHENEVER SQLERROR GOTO conn_err; 
	EXEC SQL CONNECT :username IDENTIFIED BY :passwd USING :dbstring; 
	printf("connect success.\n"); 
 
	EXEC SQL WHENEVER SQLERROR CONTINUE; 
	 
	testMethod1(); 
	testMethod2(); 
	testMethod3(); 
	testMethod4(); 
 
	EXEC SQL COMMIT RELEASE; 
	printf("Testing is Ok.\n"); 
	exit(0); 
		 
conn_err: 
	printf("connect database failed!\n"); 
	EXEC SQL WHENEVER SQLERROR CONTINUE; 
	EXEC SQL ROLLBACK RELEASE; 
	exit(1); 
sql_err: 
	printf("implements sql statements failed!\n"); 
	EXEC SQL WHENEVER SQLERROR CONTINUE; 
	EXEC SQL ROLLBACK RELEASE; 
	exit(1); 
} 
 
void testMethod1() 
{ 
	EXEC SQL BEGIN DECLARE SECTION; 
		char sqlstmt1[1024]; 
	EXEC SQL END DECLARE SECTION; 
	int opt,ch; 
	int i; 
 
	printf("Please input e exit the test method 1,input others continue.\n"); 
	fflush(stdin); 
	while((opt = getchar()) != 'e') 
	{		 
		fflush(stdin); 
		printf("please input sql statement for dynamic method1:\n"); 
		memset(sqlstmt1, 0, sizeof(sqlstmt1)); 
		for(i = 0; (i < 1024) && ((ch=getchar()) != EOF) && (ch != '\n'); i++) 
			sqlstmt1[i] = ch; 
 
		/* implements operation. */ 
		printf("start run sql :%s.\n",sqlstmt1); 
		 
		EXEC SQL EXECUTE IMMEDIATE :sqlstmt1; 
		if (sqlca.sqlcode < 0) 
		{ 
			printf("%70s\n", sqlca.sqlerrm.sqlerrmc); 
			printf("Implement sql failed!\n"); 
			EXEC SQL ROLLBACK; 
		}		 
		printf("Implement Success.affective %d recordsets.\n", sqlca.sqlerrd[2]); 
		EXEC SQL COMMIT; 
 
		fflush(stdin); 
		printf("Please input e exit the test method 1,input others continue.\n"); 
	} 
} 
 
void testMethod2() 
{ 
	EXEC SQL BEGIN DECLARE SECTION; 
		char sqlstmt2[1024]; 
		int ccode, dcode, ecode; 
	EXEC SQL END DECLARE SECTION; 
 
	int opt; 
 
	strcpy(sqlstmt2, "update employee set ccode=:v1, dcode=:v2 where ecode=:v3"); 
	EXEC SQL PREPARE UPDATE_EMPLOYEE FROM :sqlstmt2; 
 
	fflush(stdin); 
	printf("Please input e exit the test method 2,input others continue.\n"); 
	while((opt = getchar()) != 'e') 
	{ 
		fflush(stdin); 
		printf("please input ecode:");scanf("%d",&ecode); 
		printf("please input ccode:");scanf("%d",&ccode); 
		printf("please input dcode:");scanf("%d",&dcode); 
		printf("start run sql :update employee set ccode=%d, dcode=%d where ecode=%d.\n",ccode,dcode,ecode); 
		 
		/* implements operation. */ 
		EXEC SQL EXECUTE UPDATE_EMPLOYEE USING :ccode, :dcode, :ecode; 
		if (sqlca.sqlcode < 0) 
		{ 
			printf("Implement sql failed!\n%70s\n", sqlca.sqlerrm.sqlerrmc); 
			EXEC SQL ROLLBACK; 
		} 
		else 
		{ 
			printf("Implement Success.affective %d recordsets.\n", sqlca.sqlerrd[2]); 
			EXEC SQL COMMIT; 
		} 
 
		fflush(stdin); 
		printf("Please input e exit the test method 2,input others continue.\n"); 
	} 
} 
 
void testMethod3() 
{ 
	EXEC SQL BEGIN DECLARE SECTION; 
		char sqlstmt3[1024]; 
		int ccode; 
		char ename[30]; 
		char duty[64]; 
		char cname[30]; 
		char dname[30]; 
	EXEC SQL END DECLARE SECTION; 
	int opt; 
 
	strcpy(sqlstmt3, "select emp.ename, cmp.cname, edp.dname, emp.duty from employee emp,company cmp,edepartment edp where emp.ccode=:v1 and cmp.ccode=emp.ccode and edp.dcode=emp.dcode"); 
	EXEC SQL PREPARE select_emp FROM :sqlstmt3; 
 
	fflush(stdin); 
	printf("Please input e exit the test method 3,input others continue.\n"); 
	while((opt = getchar()) != 'e') 
	{ 
		fflush(stdin); 
		printf("please input ccode:");scanf("%d",&ccode); 
		printf("start run sql...\n"); 
		 
		/* implements operation. */ 
		EXEC SQL DECLARE empcus CURSOR FOR select_emp; 
		EXEC SQL OPEN empcus USING :ccode; 
 
		EXEC SQL WHENEVER NOT FOUND DO break; 
		printf("%-30s %-30s %-30s %-60s \n","employee name","company","department","duty"); 
		while(1) 
		{ 
			EXEC SQL FETCH	empcus INTO :ename, :cname, :dname, :duty;			 
			printf("%-30s %-30s %-30s %-60s \n", ename, cname, dname, duty); 
		} 
		EXEC SQL WHENEVER SQLERROR CONTINUE; 
		EXEC SQL CLOSE empcus; 
 
		if (sqlca.sqlcode < 0) 
		{ 
			printf("Implement sql failed!\n%70s\n", sqlca.sqlerrm.sqlerrmc); 
			EXEC SQL ROLLBACK; 
		} 
		else 
		{ 
			printf("Implement Success.affective %d recordsets.\n", sqlca.sqlerrd[2]); 
			EXEC SQL COMMIT; 
		} 
 
		fflush(stdin); 
		printf("Please input e exit the test method 3,input others continue.\n"); 
	} 
} 
 
void testMethod4() 
{ 
	EXEC SQL BEGIN DECLARE SECTION; 
		char sqlstmt4[1024]; 
	EXEC SQL END DECLARE SECTION; 
 
	int i,loopflag,opt; 
	char bindvar[MAX_VNAME_LEN]; 
	char * ptmp; 
 
	SQLDA * bind_desc; 
	SQLDA * sel_desc; 
 
	/* initializes descriptors. */ 
	if ((sel_desc = sqlald((int)MAX_SELECT_ITEMS, (int)MAX_VNAME_LEN, (int)MAX_INAME_LEN)) == (SQLDA *)0) 
	{ 
		printf("initializes select descriptor failed!\n"); 
		return; 
	} 
 
	if ((bind_desc = sqlald((int)MAX_SELECT_ITEMS, (int)MAX_VNAME_LEN, (int)MAX_INAME_LEN)) == (SQLDA *)0) 
	{ 
		printf("initializes bind descriptor failed!\n"); 
		return; 
	} 
 
	/* allocates memory for descriptors. */ 
	AllocateDescriptors(sel_desc, bind_desc, MAX_SELECT_ITEMS); 
 
	/* test4 is runing. */ 
	fflush(stdin); 
	printf("Please input e exit the test method 4,input others continue.\n"); 
	while((opt = getchar()) != 'e') 
	{ 
		(void)setjmp(restore_err); 
 
		memset(sqlstmt4, 0, sizeof(sqlstmt4)); 
		getInputStmt(sqlstmt4); 
 
		if ((strncmp(sqlstmt4, "exit", 4) == 0) || (strncmp(sqlstmt4, "EXIT", 4) == 0)) 
			goto rebegin; 
				 
		EXEC SQL WHENEVER SQLERROR DO errorProc(); 
 
		EXEC SQL PREPARE S FROM :sqlstmt4; 
		EXEC SQL DECLARE C CURSOR FOR S; 
 
		bind_desc->N = MAX_SELECT_ITEMS; 
		EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_desc; 
		if (bind_desc->F < 0) 
		{ 
			printf("the count of bind variables is %d, don't be larger than MAX_SELECT_ITEMS %d.\n",  
				-(bind_desc->F), MAX_SELECT_ITEMS); 
			continue; 
		} 
		bind_desc->N = bind_desc->F; 
 
		for(loopflag = 1;loopflag; ) 
		{ 
			fflush(stdin); 
			for(i = 0; i < bind_desc->F; i++) 
			{ 
				/* input variable binding */ 
				printf("please input the value of %.*s:", (int)bind_desc->C[i], bind_desc->S[i]); 
				fgets(bindvar, sizeof(bindvar), stdin); 
				if (bindvar[0] == '\n') 
				{ 
					loopflag = 0; 
					break; 
				} 
 
				/* bind the variable with bind_desc */ 
				ptmp = (char *) realloc(bind_desc->V[i], bind_desc->L[i]+1); 
				if (ptmp != NULL) 
					bind_desc->V[i] = ptmp; 
				strncpy(bind_desc->V[i], bindvar, strlen(bindvar)-1); 
				bind_desc->L[i] = strlen(bindvar)-1; 
				bind_desc->T[i] = 1; 
 
				/* set the value of indicators. */  
				if ((strncmp(bind_desc->V[i], "NULL", 4) == 0) ||  
					(strncmp(bind_desc->V[i], "null", 4)== 0)) 
					*bind_desc->I[i] = -1; 
				else 
					*bind_desc->I[i] = 0; 
					 
			} 
			if (!loopflag) break; 
			else if (!i) loopflag = 0; 
 
			/* open cursor */ 
			EXEC SQL OPEN C USING DESCRIPTOR bind_desc; 
 
			if ((strncmp(sqlstmt4, "SELECT", 6) == 0) || (strncmp(sqlstmt4, "select", 6) == 0)) 
				QueryProcess(sel_desc, bind_desc); 
 
		} 
		 
		rebegin: 
			fflush(stdin); 
			printf("Please input e exit the test method 4,input others continue.\n"); 
	} 
	UnAllocateDescriptors(sel_desc, bind_desc, MAX_SELECT_ITEMS); 
	sqlclu(bind_desc); 
	sqlclu(sel_desc); 
	EXEC SQL WHENEVER SQLERROR CONTINUE; 
	EXEC SQL CLOSE C; 
	EXEC SQL COMMIT WORK RELEASE; 
	exit(0); 
} 
 
void AllocateDescriptors(SQLDA * sel_desc, SQLDA * bind_desc, int maxsize) 
{ 
	int i; 
	for (i = 0; i < maxsize; i++) 
	{ 
		sel_desc->V[i] = (char *)malloc(1); 
		assert(sel_desc->V[i]); 
		sel_desc->I[i] = (short *)malloc(sizeof(short)); 
		assert(sel_desc->I[i]); 
		bind_desc->V[i] = (char *)malloc(1); 
		assert(bind_desc->V[i]); 
		bind_desc->I[i] = (short *)malloc(sizeof(short)); 
		assert(bind_desc->I[i]); 
	} 
} 
 
void UnAllocateDescriptors(SQLDA * sel_desc, SQLDA * bind_desc, int maxsize) 
{ 
	int i; 
	for (i = 0; i < maxsize; i++) 
	{ 
		free(sel_desc->V[i]); 
		assert(sel_desc->V[i]); 
		free(sel_desc->I[i]); 
		assert(sel_desc->I[i]); 
		free(bind_desc->V[i]); 
		assert(bind_desc->V[i]); 
		free(bind_desc->I[i]); 
		assert(bind_desc->I[i]); 
	} 
} 
 
short getInputStmt(char * stmtarr) 
{ 
	int ch,i; 
	fflush(stdin); 
	printf("please input dynamic sql statement(input 'exit' to leave):\n"); 
	for(i = 0; (i < 1024) && ((ch=getchar()) != EOF) && (ch != '\n'); i++) 
		stmtarr[i] = ch; 
	return 1; 
} 
 
void errorProc() 
{ 
	printf("Occurs an error :\n%s\n",sqlca.sqlerrm.sqlerrmc); 
	EXEC SQL WHENEVER SQLERROR CONTINUE; 
	EXEC SQL ROLLBACK; 
	longjmp(restore_err, 1); 
} 
 
void QueryProcess(SQLDA * sel_desc, SQLDA * bind_desc) 
{ 
	int i, isnull, precision, scale; 
	SELDA_LEN SeldaLen[MAX_SELECT_ITEMS]; 
	char ColName[MAX_VNAME_LEN+1]; 
	EXEC SQL WHENEVER SQLERROR DO errorProc(); 
	sel_desc->N = MAX_SELECT_ITEMS; 
	EXEC SQL DESCRIBE SELECT LIST FOR S INTO sel_desc; 
 
	if (sel_desc->F < 0) 
	{ 
		printf("the count of bind variables is %d, don't be larger than MAX_SELECT_ITEMS %d.\n",  
				-(bind_desc->F), MAX_SELECT_ITEMS); 
		return; 
	} 
	sel_desc->N = sel_desc->F; 
	 
	for(i = 0; i < sel_desc->F; i++) 
	{ 
		sqlnul((unsigned short*)&sel_desc->T[i], (unsigned short*)&sel_desc->T[i], &isnull); 
		switch (sel_desc->T[i]) 
		{ 
		case 1:	/* CHAR datatype: no change in length 
				needed, except possibly for TO_CHAR 
				conversions (not handled here). */ 
				break; 
		case 2:	/* NUMBER datatype: use SQLNumberPrecV6() to 
				extract precision and scale. */ 
			sqlprc(&(sel_desc->L[i]), &precision, &scale); 
			if (precision == 0) precision = 38; 
			if (scale > 0) 
				sel_desc->L[i] = sizeof(float); 
			else 
				sel_desc->L[i] = sizeof(int); 
 
			SeldaLen[i].precision = precision; 
			SeldaLen[i].scale = scale; 
			break; 
		case 8 : /* LONG datatype */ 
				sel_desc->L[i] = 240; 
				break; 
		case 11 : /* ROWID datatype */ 
				sel_desc->L[i] = 18; 
				break; 
		case 12 : /* DATE datatype */ 
				sel_desc->L[i] = 9; 
				break; 
		case 23 : /* RAW datatype */ 
				break; 
		case 24 : /* LONG RAW datatype */ 
				sel_desc->L[i] = 240; 
				break; 
		} 
 
		if (sel_desc->T[i] != 2) 
			sel_desc->V[i] = (char *) realloc(sel_desc->V[i], 
				sel_desc->L[i] + 1); 
		else 
			sel_desc->V[i] = (char *) realloc(sel_desc->V[i], 
				sel_desc->L[i]); 
 
		/* get column name */ 
		memset(ColName, 0, MAX_VNAME_LEN); 
		strncpy(ColName, sel_desc->S[i], sel_desc->C[i]); 
 
		/* get the suitable len of displaying column and value. */ 
		if (sel_desc->T[i] == 2) 
			if (scale > 0) 
			{ 
				SeldaLen[i].precision = (precision > sel_desc->C[i])? precision : sel_desc->C[i]; 
			} 
			else 
			{ 
				SeldaLen[i].precision = (sel_desc->L[i] > sel_desc->C[i])? sel_desc->L[i] : sel_desc->C[i]; 
			} 
		else 
		{ 
			SeldaLen[i].precision = (sel_desc->L[i] > sel_desc->C[i])? sel_desc->L[i] : sel_desc->C[i];			 
		} 
		printf ("%-*s ", SeldaLen[i].precision, ColName); 
 
 
		/* Coerce ALL datatypes except for LONG RAW and NUMBER to character. */ 
		if (sel_desc->T[i] != 24 && sel_desc->T[i] != 2) 
			sel_desc->T[i] = 1; 
		/* Coerce the datatypes of NUMBERs to float or int depending on the scale. */ 
		if (sel_desc->T[i] == 2) 
			if (scale > 0) 
				sel_desc->T[i] = 4; /* float */ 
			else 
				sel_desc->T[i] = 3; /* int */	 
	} 
	printf("\n"); 
 
	EXEC SQL WHENEVER NOT FOUND GOTO end_select_loop; 
	for(;;) 
	{ 
		EXEC SQL FETCH C USING DESCRIPTOR sel_desc; 
		/* Since each variable returned has been coerced to a 
		character string, int, or float very little processing 
		is required here. This routine just prints out the 
		values on the terminal. */ 
		for (i = 0; i < sel_desc->F; i++) 
		{ 
			if (*sel_desc->I[i] < 0) 
				printf ("%-*c ", SeldaLen[i].precision, ' '); 
			else 
				if (sel_desc->T[i] == 3) /* int datatype */ 
					printf ("%*d ", SeldaLen[i].precision, *(int *)sel_desc->V[i]); 
				else if (sel_desc->T[i] == 4) /* float datatype */ 
					printf ("%*.*f ", SeldaLen[i].precision, SeldaLen[i].scale, *(float *)sel_desc->V[i]); 
				else /* character string */ 
					printf ("%-.*s ", SeldaLen[i].precision, sel_desc->V[i]); 
		} 
		printf ("\n"); 
	} 
	end_select_loop: 
		return; 
}