|
大侠,偶还是把代码给你,吧,这样你会很明白.
/*
HERE,we get every column's values size and write value into file,
just same size with defined.
TO get it,we use L to get every size and use L[0]+..+L[END] as
a buffer size,we write all column value into the buffer and then
write buffer into file.
TO do more is,we can malloc more buffer and write more big block into file
to save time.
*/
#include <stdio.h>
#include <string.h>
#include <setjmp.h>
#include <sqlda.h>
#include <stdlib.h>
#include <sqlcpr.h>
#include <time.h>
#include <sys/timeb.h>
#include <sys/types.h>
#define MAX_SELECT_ITEMS 30
#define MAX_NAME_SIZE 50
/*funcs
*/
int getNowTime(int *hour,int *min,int *sec,short *mill);
void printSqlda(SQLDA *sqlDa);
void sql_error();
int intValueSize(int intValue);
void printUseTime(int h1,int m1,int s1,int mi1,int h2,int m2,int s2,int mi2);
/*end funcs
*/
EXEC SQL INCLUDE sqlda;
EXEC SQL INCLUDE sqlca;
SQLDA *selda;
char *username = "abc/abc@ora803abc";
char *stmt=0;
char fileName[20]="tempData.txt";
/*==========main==========*/
void main(int argc,char *argv[]) {
int sqlaldRet;
int row_count;
int sli;
int null_ok;
int precision, scale;
int row2, sli2;/*use in write into file.*/
char *fileHeader=0;
int fileHeaderSize=0;
int fileHeaderSizeSize1=0;
int fileHeaderSizeSize2=0;
char *fileHeaderP=0;
char tempIntStr[10];
char *buffer=0;
char *p=NULL;
FILE *fd;
int bufferSize=0;
char *bufferP=0;
int hour,min,sec;
int hour2,min2,sec2;
short mil;
short mil2;
stmt=(char*)malloc(100);
printf("input table name:" ;
fgets(stmt,100,stdin);
printf("\n" ;
printf("input file name:" ;
/*
fgets(fileName,20,stdin);
*/
/*
strcpy(stmt,argv[1]);
*/
printf("you have input sql is:%s\n",stmt);
printf("you have input file name:%s\n",fileName);
fd=fopen(fileName,"w" ;
if(fd==NULL){
printf("can not open file tempResult1.txt!\n" ;
return;
}
EXEC SQL CONNECT :username;
if (sqlca.sqlcode == 0)
printf("Connected.\n" ;
else {
printf("Cannot connect %s.\n",username);
exit(EXIT_FAILURE);
}
EXEC SQL WHENEVER SQLERROR DO sql_error();
sqlaldRet=selda = sqlald(MAX_SELECT_ITEMS, MAX_NAME_SIZE, 1);
if(sqlaldRet<=0){
printf("error when sqlald..\n" ;
return;
}
EXEC SQL PREPARE S FROM :stmt;
EXEC SQL DECLARE C CURSOR FOR S;
EXEC SQL OPEN C;
EXEC SQL DESCRIBE SELECT LIST FOR S INTO selda;
/*--now print info about selda--*/
/*
printf("--after describe select into sqlda--\n" ;
printSqlda(selda);
*/
selda->N = selda->F;
/*malloc size of mem for every value*/
fileHeader=(char*)malloc(1000);
fileHeaderP=fileHeader;
fileHeaderP+=12;/*used to as [2333..] as headerSize*/
for (sli = 0; sli < selda->N; sli++){
/*after describe ,we can deal with every select item's name,S[sli] an C[sli],
we just put them and write it as data file header.
*/
strncpy(fileHeaderP,selda->S[sli],selda->C[sli]);
fileHeaderP+=selda->C[sli];
fileHeaderSize+=selda->C[sli];
sprintf(fileHeaderP,"(%d)",selda->C[sli]);
if(selda->C[sli]>10){
fileHeaderP+=2+2;
}else{
if(selda->C[sli]<10&&selda->C[sli]>0){
fileHeaderP+=3;
}else{
printf("ERROR,too big columnNameSize" ;
fileHeaderP+=0;
}
}
/*now , oracle have set value's length into L
but,we must reset length of V to make it can contain all
value from value of all type.
and we must reset L to use L malloc mem to store value.
*/
/*reset internal type by oracle*/
sqlnul((unsigned short *)&(selda->T[sli]), (unsigned short *)&(selda->T[sli]), &null_ok);
switch (selda->T[sli])
{
case 1 : /* CHAR datatype: no change in length
needed, except possibly for TO_CHAR
conversions (not handled here).
*/
break;
case 2 : /* NUMBER datatype: use sqlprc() to
extract precision and scale.
*/
/*
sqlprc ((unsigned long *)&(selda->L[sli]), &precision, &scale);
*/
/* Allow for maximum size of NUMBER.
*/
/*
if (precision == 0) precision = 40;
*/
/* Also allow for decimal point and
possible sign.
*/
/* convert NUMBER datatype to FLOAT if scale > 0,
INT otherwise.
*/
/*
if (scale > 0)
selda->L[sli] = sizeof(float);
else
selda->L[sli] = sizeof(int);
break;
*/
/*we set it as 10*/
selda->L[sli]=10;
break;
case 8 : /* LONG datatype */
selda->L[sli] = 240;
break;
case 11 : /* ROWID datatype */
case 104 : /* Universal ROWID datatype */
selda->L[sli] = 18;
break;
case 12 : /* DATE datatype */
selda->L[sli] = 9;
break;
case 23 : /* RAW datatype */
break;
case 24 : /* LONG RAW datatype */
selda->L[sli] = 240;
break;
}
selda->V[sli] = (char *)malloc(selda->L[sli]);
printf("in txt size:%d\n",selda->L[sli]);
/* here we add malloc I[sil] to make the can set I to indicate
whether the current row's column is NULL(-1),then can deal.
*/
selda->I[sli]=(short*)malloc(sizeof(short));
bufferSize+=selda->L[sli];
selda->T[sli]=1;
}
fileHeaderP+=1;
*fileHeaderP='\0';
fileHeaderP=fileHeader;
memset(fileHeaderP,' ',12);
fileHeaderSize=strlen(fileHeader);
fileHeaderSize+=2+10;
sprintf(tempIntStr,"[%d]",fileHeaderSize);
strncpy(fileHeaderP,tempIntStr,intValueSize(fileHeaderSize)+2);
printf("%s\n",fileHeader);
printf("header size:%d\n",fileHeaderSize);
/*write it to file*/
/*
fwrite(fileHeader,fileHeaderSize,1,fd);
*/
free(fileHeader);
fileHeaderP=0;
buffer=(char*)malloc(bufferSize);
bufferP=buffer;
/* FETCH each row selected and print the column values. */
EXEC SQL WHENEVER NOT FOUND GOTO end_select_loop;
getNowTime(&hour,&min,&sec,&mil);
printf("before do the sql,time is(HOUR:%d,MIN:%d,SEC:%d,MIL:%u)\n",hour,min,sec,mil);
for (;
{
EXEC SQL FETCH C USING DESCRIPTOR selda;
/*
printf("--after fetch using descriptor --\n");
printSqlda(selda);
*/
/* 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 (sli = 0; sli < selda->F; sli++)
{
if(*selda->I[sli]==-1){
/*
printf("NULL");
*/
memset(bufferP,' ',selda->L[sli]);
bufferP+=selda->L[sli];
}else{
if(*selda->I[sli]==0){
/*
printf("%s",selda->V[sli]);
*/
sprintf(bufferP,"%s",selda->V[sli]);
bufferP+=selda->L[sli];
}else{
printf("have been truncated:%d ",selda->I[sli]);
}
}
}
/*
printf ("\n");
printf("[%s]\n",buffer);
*/
fwrite(buffer,bufferSize,1,fd);
/*when end one row,reset all*/
bufferP=buffer;
}
end_select_loop:
/*write tail*/
fileHeader=(char*)malloc(100);
memset(fileHeader,'\0',100);
sprintf(fileHeader,"[%d]",sqlca.sqlerrd[2]);
fwrite(fileHeader,sizeof(fileHeader),1,fd);
fclose(fd);
printf("\n%d rows retrieved\n", sqlca.sqlerrd[2]);
EXEC SQL ROLLBACK RELEASE;
getNowTime(&hour2,&min2,&sec2,&mil2);
printf("use time:");
if(hour2<hour){
hour-=12;
}
printf("%d hour,",hour2-hour);
if(min2<min){
}
printf("after do the sql,time is(HOUR:%d,MIN:%d,SEC:%d,MIL:%u)\n",hour2,min2,sec2,mil2);
printUseTime(hour,min,sec,(int)mil,hour2,min2,sec2,(int)mil2);
exit(EXIT_SUCCESS);
return;
/*write tail*/
fileHeader=(char*)malloc(100);
memset(fileHeader,'\0',100);
sprintf(fileHeader,"[%d]",sqlca.sqlerrd[2]);
fwrite(fileHeader,sizeof(fileHeader),1,fd);
fclose(fd);
printf("\n%d rows retrieved\n", sqlca.sqlerrd[2]);
EXEC SQL ROLLBACK RELEASE;
getNowTime(&hour2,&min2,&sec2,&mil2);
printf("after do the sql,time is(HOUR:%d,MIN:%d,SEC:%d,MIL:%u)\n",hour2,min2,sec2,mil2);
printUseTime(hour,min,sec,(int)mil,hour2,min2,sec2,(int)mil2);
exit(EXIT_SUCCESS);
}
/*==========end main=========*/
/*---------------------------------
*/
void printSqlda(SQLDA *sqlDa){
/*(long N)sli or p's max num*/
printf("1 long N)sli or p's max num:%d\n",sqlDa->N);
/*(F)sli or p's realy num*/
printf("6 F)sli or p's realy num:%d\n",sqlDa->F);
/*(char **V)address of sli or bv's value's address*/
int num=sqlDa->F;
int i=0;
printf("2 char **V)address of sli or bv's value's address\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%s\n",sqlDa->V[0],sqlDa->V);
}
/*3(long *L)pointer to SLI or BV value's length*/
printf("3 long *L)pointer to SLI or BV value's length\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%d\n",sqlDa->L,sqlDa->L);
}
/*4(short *T)pointer to SLI or BV value's type*/
printf("4 short *T)pointer to SLI or BV value's type\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%d\n",sqlDa->T,sqlDa->T);
}
/*5(short **I)pointer to IV value's address*/
printf("5 short **I)pointer to IV value's address\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%d\n",sqlDa->I,sqlDa->I);
}
/*7 char **S) pointer to SLI or P name's address*/
printf("7 char **S) pointer to SLI or P name's address\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%s\n",sqlDa->S,sqlDa->S);
}
/*8 short *M) pointer to SLI or P name's max length*/
printf("8 short *M) pointer to SLI or P name's max length\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%d\n",sqlDa->M,sqlDa->M);
}
/*9:(short *C) pointer to SLI or P name's current length*/
printf("9:(short *C) pointer to SLI or P name's current length\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%d\n",sqlDa->C,sqlDa->C);
}
/*-----------------------------------------------*/
/*10:(char **X) pointer to IV name's address*/
printf("10:(char **X) pointer to IV name's address\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%s\n",sqlDa->X,sqlDa->X);
}
/*11:(*Y) pointer to IV name max length*/
printf("11:(*Y) pointer to IV name max length\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%d\n",sqlDa->Y,sqlDa->Y);
}
/*12:(*Z) pointer to IV name current length*/
printf("12:(short *Z) pointer to IV name current length\n");
for(i=0;i<num;i++){
printf(" address:%x,value:%d\n",sqlDa->Z,sqlDa->Z);
}
}
/*------------------------------------------------*/
void sql_error(){
char msgbuf[512];
size_t msgbuf_len, msg_len;
msgbuf_len = sizeof(msgbuf);
sqlglm(msgbuf, &msgbuf_len, &msg_len);
printf ("\n\n%.*s\n", msg_len, msgbuf);
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL ROLLBACK WORK RELEASE;
exit(EXIT_FAILURE);
}
int intValueSize(int intValue){
if(intValue>=0&&intValue<10)
return 1;
if(intValue>=10&&intValue<100)
return 2;
if(intValue>=100&&intValue<1000)
return 3;
if(intValue>=1000&&intValue<10000)
return 4;
} |
|