📄 testallmethods.pc
字号:
/***********************************************************
* TestAllMethods.pc
* created by Caoqing on 2003.12.24
*
* This project is used to realize dynamic sql statments used
* four methods.
*
*
*
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <assert.h>
#include <sqlca.h>
#include <sqlda.h>
#include <sqlcpr.h>
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -