📄 serverdb.c
字号:
DoCommit(&lda) ; else DoRollback(&lda); } SetStrByte2(rowbuf,rownum); userlog("last packet:%d\n",rownum); sendlen=PacketSelectQR(sendbuf,fdbuf,fdlen,rownum, rowbuf,rowlen,1); /* 分配缓冲区用于发送内容 */ tpbuf=tpalloc("CARRAY",NULL,sendlen); memcpy(tpbuf,sendbuf,sendlen); userlog("tpsend,rowlen=%d,trownum=%d\n",sendlen,trownum); DebugPrint(tpbuf,100); tpsend(svcinfo->cd,tpbuf,sendlen,TPNOTIME,&revent); /* 可能要增加对tpsend返回结果的处理 */ DebugPrintHeader((PacketQR*)tpbuf); sprintf((char*)szOCIErrMsg,"提取到%d行记录!",trownum); userlog("%s\n",szOCIErrMsg); tpreturn(TPSUCCESS,0,tpbuf,sendlen,0); return; } /* if(cda.rc!=NULL_VALUE_RETURNED) { oci_error(&cda); goto FailReturn; } */ } ++trownum; /* userlog("Fetch %d/%d row...\n",rownum,trownum); */ if((trownum>nOCIRowLimits)&&(nOCIRowLimits>0)) continue; ++rownum; for(col = 0; col < nOCIFieldNum ; col++) { /* 检查NULL值 */ if (def[col].indp<0) /* 追加一个空字段 */ { *rowpos='\0'; rowpos+=LEN_BYTE_1; rowlen+=LEN_BYTE_1; } else /* 追加一个字段内容 */ { /* switch (desc[col].dbtype) { case FLOAT_TYPE: fdvallen=sprintf(rowpos+LEN_BYTE_1,"%f",def[col].flt_buf); break; case INT_TYPE: fdvallen=sprintf(rowpos+LEN_BYTE_1,"%d",def[col].int_buf); break; default: fdvallen=sprintf(rowpos+LEN_BYTE_1,"%s", def[col].buf); break; } */ fdvallen=sprintf(rowpos+LEN_BYTE_1,"%s",def[col].buf); /* userlog("%d\n",fdvallen); */ *(unsigned char*)rowpos=fdvallen; rowpos+=LEN_BYTE_1+fdvallen; rowlen+=LEN_BYTE_1+fdvallen; } } /* 追加\n */ *rowpos='\n'; rowpos++; rowlen++; if(rowlen+PACKET_MIN_LEN+800>=MAX_SENDBUF_LEN) { SetStrByte2(rowbuf,rownum); userlog("continue packet %d\n",rownum); sendlen=PacketSelectQR(sendbuf,fdbuf,fdlen,rownum, rowbuf,rowlen,0); /* 分配缓冲区用于发送内容 */ tpbuf=tpalloc("CARRAY",NULL,sendlen); memcpy(tpbuf,sendbuf,sendlen); DebugPrint(tpbuf,100); DebugPrintHeader((PacketQR*)tpbuf); userlog("tpsend,rowlen=%d,trownum=%d\n",sendlen,trownum); tpsend(svcinfo->cd,tpbuf,sendlen,TPNOTIME,&revent); /* 可能要增加对tpsend返回结果的处理 */ /* 重新初始化新的记录组 */ rownum=0; *rowbuf='\0'; rowpos=rowbuf+LEN_BYTE_2; rowlen=LEN_BYTE_2; ++nOCIPacketNo; } }FailReturn: /* 与数据库断开连接,尝试重新连接 */ if(nOCIErrNo==3114) { tmStart=time(NULL); while(time(NULL)<tmStart+10) { retcode=ReConnectSQLServer(); if(retcode==0) goto RestartSQLProcess; if(retcode==-2) break; } } if(nOCITranID==0) { if(nOCIErrNo==0) DoCommit(&lda) ; else DoRollback(&lda); } printf("nOCIErrNo=%d,szOCIErrMsg=%s\n",nOCIErrNo,szOCIErrMsg); sendlen=PacketNonselectQR(sendbuf); /* 分配缓冲区用于发送内容 */ tpbuf=tpalloc("CARRAY",NULL,sendlen); memcpy(tpbuf,sendbuf,sendlen); userlog("%s\n",szOCIErrMsg); DebugPrint(tpbuf,sendlen); /* tpreturn(TPFAIL,nOCIErrNo,tpbuf,sendlen,0); */ tpreturn(TPSUCCESS,nOCIErrNo,tpbuf,sendlen,0);}/********************************************************************//* 函数: PacketInit *//* 用途: 初始化数据包头结构 *//* 原型: void PacketInit(PacketQR* packet); *//* 参数: packet -- 数据包头 *//* 返回: 无 *//********************************************************************/void PacketInit(PacketQR *packet){ int i; memset(packet,'\0',sizeof(PacketQR)); strcpy(packet->PacketID,"8899"); SetStrByte4(packet->PacketLen,sizeof(PacketQR)); strcpy(packet->UserID,"8899"); SetStrByte4(packet->TranID,nOCITranID); packet->NextFlag='N'; for(i=0;i<i;i++) packet->DataPart[i]='N'; packet->SQLType='X';}/********************************************************************//* 函数: UnpacketSQL *//* 用途: 解包SQL(暂时不做过多检查) *//* 原型: int UnpacketSQL(char* buf,long len,char* pszSQL); *//* 参数: buf -- 数据包缓冲区 *//* len -- 数据包长度 *//* pszSQL -- 存放提取出的SQL语句 *//* 返回: 0 = 成功,同时在pszSQL中存放SQL语句 *//* -1 = 失败,如格式错误等 *//********************************************************************/int UnpacketSQL(char* buf,long len,char* pszSQL){ PacketQR* hdr; PartDesc* part; hdr=(PacketQR*)buf;#ifdef _DEBUG DebugPrintHeader(hdr);#endif nOCITranID=GetStrByte4(hdr->TranID); nOCIRowLimits=GetStrByte4(hdr->RowLimits); userlog("nOCIRowLimits=%d\n",nOCIRowLimits); userlog("TranID=%d\n",nOCITranID); /* 检查头是否正常(不含SQL语句视为非法) */ if(hdr->DataPart[DATA_SQL]!='Y') return(-1); part=(PartDesc*)(buf+sizeof(PacketQR)+DATA_SQL*sizeof(PartDesc));#ifdef _DEBUG printf("part=(%d,%d)\n",GetStrByte2(part->PartLen),GetStrByte2(part->PartShift));#endif strncpy(pszSQL,buf+GetStrByte2(part->PartShift),GetStrByte2(part->PartLen)); pszSQL[GetStrByte2(part->PartLen)]='\0'; myuserlog("SQLStatement:",pszSQL); return(0);}/* 函数,打包数据 *//********************************************************************//* 函数: PacketNonselectQR *//* 用途: 打包数据(对非SQL Select类型) *//* 原型: int PacketNonselectQR(char* buf); *//* 参数: buf -- 数据包缓冲区 *//* 返回: >0 ,数据包长度 *//********************************************************************/int PacketNonselectQR(char *buf){ PacketQR* hdr; PartDesc* partRC, *partOD, *partOV; int partRCLen, partODLen, partOVLen; int partRCShift, partODShift, partOVShift; int len1,len2; char szODBuf[2048]; char szOVBuf[2048]; hdr=(PacketQR*)buf; PacketInit(hdr); hdr->NextFlag='N'; /* 无后续结果 */ hdr->DataPart[DATA_SQL]='N'; /* 无SQL语句 */ hdr->DataPart[DATA_RETCODE]='Y'; /* 有返回码 */ partRC=(PartDesc*)(buf+sizeof(PacketQR)); partRCLen=LEN_BYTE_4+strlen((char*)szOCIErrMsg); SetStrByte2(partRC->PartLen,partRCLen); if((nOCIOutNum>0)&&(nOCIErrNo==0)) { hdr->DataPart[DATA_OUTDESC]='Y'; /* (暂时)无输出变量 */ hdr->DataPart[DATA_OUTDATA]='Y'; partODLen=PacketOutDesc(szODBuf); partOVLen=PacketOutValue(szOVBuf); partOD=(PartDesc*)(buf+sizeof(PacketQR)+sizeof(PartDesc)); partOV=(PartDesc*)(buf+sizeof(PacketQR)+2*sizeof(PartDesc)); partRCShift=sizeof(PacketQR)+3*sizeof(PartDesc); partODShift=partRCShift+partRCLen; partOVShift=partODShift+partODLen; SetStrByte2(partRC->PartShift,partRCShift); SetStrByte2(partOD->PartLen,partODLen); SetStrByte2(partOD->PartShift,partODShift); SetStrByte2(partOV->PartLen,partOVLen); SetStrByte2(partOV->PartShift,partOVShift); } else { partRCShift=sizeof(PacketQR)+sizeof(PartDesc); SetStrByte2(partRC->PartShift,partRCShift); hdr->DataPart[DATA_OUTDESC]='N'; /* (暂时)无输出变量 */ hdr->DataPart[DATA_OUTDATA]='N'; } hdr->DataPart[DATA_FDDESC]='N'; /* 无字段清单 */ hdr->DataPart[DATA_ROWS]='N'; /* 无返回记录集 */ switch(nOCIFunction) { case(FT_SELECT): hdr->SQLType=ST_SELECT; break; case(FT_UPDATE): hdr->SQLType=ST_UPDATE; break; case(FT_INSERT): hdr->SQLType=ST_INSERT; break; case(FT_DELETE): hdr->SQLType=ST_DELETE; break; default: hdr->SQLType=ST_UNKNOWN; break; } /* 用RowLimits字段返回受影响的记录数 */ SetStrByte4(hdr->RowLimits,nOCIAffectedRow); /* 填写返回码信息(5位返回码+错误信息) */ SetStrByte4(buf+partRCShift,nOCIErrNo); strncpy(buf+partRCShift+LEN_BYTE_4,(char*)szOCIErrMsg,strlen((char*)szOCIErrMsg)); if((nOCIOutNum>0)&&(nOCIErrNo==0)) { memcpy(buf+partODShift,szODBuf,partODLen); memcpy(buf+partOVShift,szOVBuf,partOVLen); return(sizeof(PacketQR)+3*sizeof(PartDesc)+partRCLen+partODLen+partOVLen); } else return(sizeof(PacketQR)+sizeof(PartDesc)+partRCLen);}/********************************************************************//* 函数: PacketSelectQR *//* 用途: 打包数据(针对SQL SELECT) *//* 原型: int PacketSelectQR(char* buf,char* fdbuf, long fdlen, *//* int rownum, char* rowbuf,long rowlen,int ok); *//* 参数: buf -- 数据包缓冲区 *//* fdbuf -- 字段清单缓冲区 *//* fdlen -- 字段清单缓冲区长度 *//* rownum -- 记录行数 *//* rowbuf -- 已打包的记录的缓冲区 *//* rowlen -- 记录缓冲区长度 *//* ok -- 包结束标志(1=结束;0=未结束) *//* 返回: >0 生成的数据包长度 *//* 附注: 对于第一个数据包要求包含字段清单 *//* 对最后一个数据包包含处理码信息 *//* 包序号在全程变量nOCIPacketNo中 *//********************************************************************/int PacketSelectQR(char *buf,char*fdbuf,long fdlen,int rownum, char*rowbuf,long rowlen,int ok){ PacketQR* hdr; char * pos; int partno=0; int len1,len2; PartDesc* partRetCode; PartDesc* partFDDesc; PartDesc* partRows; hdr=(PacketQR*)buf; PacketInit(hdr); hdr->NextFlag=(ok?'N':'Y'); /* ok=1是最后包;=0非最后包 */ hdr->DataPart[DATA_SQL]='N'; /* 无SQL语句 */ hdr->DataPart[DATA_RETCODE]=(ok?'Y':'N'); /* ok=1最后包有返回码*/ hdr->DataPart[DATA_OUTDESC]='N'; /* (暂时)无输出变量 */ hdr->DataPart[DATA_OUTDATA]='N'; hdr->DataPart[DATA_FDDESC]=((nOCIPacketNo==0)?'Y':'N'); /* 在第一个包中返回字段清单 */ hdr->DataPart[DATA_ROWS]=((rownum>0)?'Y':'N'); /* rownum表示记录行数*/ hdr->SQLType=ST_SELECT; /* 是SQL Select语句 */ /* 填写返回码信息(5位返回码+错误信息) */ /* 有返回码,填写描述信息 */ pos=buf+sizeof(PacketQR); if(hdr->DataPart[DATA_RETCODE]=='Y') { partRetCode=(PartDesc*)pos; len1=LEN_BYTE_4+strlen((char*)szOCIErrMsg); SetStrByte2(partRetCode->PartLen,len1); SetStrByte2(partRetCode->PartShift,0); pos+=sizeof(PartDesc); ++partno; } if(hdr->DataPart[DATA_FDDESC]=='Y') { partFDDesc=(PartDesc*)pos; SetStrByte2(partFDDesc->PartLen,fdlen); SetStrByte2(partFDDesc->PartShift,0); pos+=sizeof(PartDesc); ++partno; } if(hdr->DataPart[DATA_ROWS]=='Y') { partRows=(PartDesc*)pos; SetStrByte2(partRows->PartLen,rowlen); SetStrByte2(partRows->PartShift,0); pos+=sizeof(PartDesc); ++partno; } /* 安排实际位置 */ if(hdr->DataPart[DATA_RETCODE]=='Y') { len1=(size_t)(pos-buf); SetStrByte2(partRetCode->PartShift,len1); /* 拷贝数据 */ SetStrByte4(pos,nOCIErrNo); strncpy(pos+LEN_BYTE_4,(char*)szOCIErrMsg,strlen((char*)szOCIErrMsg)); pos+=GetStrByte2(partRetCode->PartLen); } if(hdr->DataPart[DATA_FDDESC]=='Y') { len1=(size_t)(pos-buf); len2=GetStrByte2(partFDDesc->PartLen); SetStrByte2(partFDDesc->PartShift,len1); /* 拷贝数据 */ memcpy(pos,fdbuf,len2); pos+=len2; } if(hdr->DataPart[DATA_ROWS]=='Y') { len1=(size_t)(pos-buf); SetStrByte2(partRows->PartShift,len1); /* 拷贝数据 */ memcpy(pos,rowbuf,rowlen); pos+=rowlen; } return((size_t)(pos-buf));}int PacketOutDesc(char *odbuf){ char *pos=odbuf; int i, len=0; *pos=nOCIOutNum; len+=LEN_BYTE_1; for(i=0;i<nOCIOutNum;i++) { pos=odbuf+len; len+=sprintf(pos,"%s?S?0?0\n",szOutNames[i]); } userlog("%s\n",odbuf); return(len);}int PacketOutValue(char *ovbuf){ char *pos=ovbuf; int i, len=0,flen; for(i=0;i<nOCIOutNum;i++) { if(sbNullFlag[i]<0) *szOutValues[i]='\0'; flen=strlen((char*)szOutValues[i]); *pos=flen; len++;pos++; strncpy(pos,(char*)szOutValues[i],flen); len+=flen;pos+=flen; } *pos='\0'; userlog("%s,%d\n",ovbuf,len); return(len);}/********************************************************************//* 函数: PacketFDDesc *//* 用途: 打包字段清单 *//* 原型: int PacketFDDesc(char* fdbuf); *//* 参数: fdbuf -- 字段缓冲区 *//* 返回: >0 生成的数据包长度 *//* 附注: 字段缓冲区格式: 个数(int)+字段信息 *//* 字段信息:名称?类型?宽度?小数点后位数+回车 *//********************************************************************/int PacketFDDesc(char *fdbuf){ char *pos=fdbuf; int i, len=0; char c; *pos=nOCIFieldNum; len+=LEN_BYTE_1; for(i=0;i<nOCIFieldNum;i++) { pos=fdbuf+len; len+=sprintf(pos,"%s?%c?%d?%d\n",desc[i].buf,ConvertDBType(desc[i].dbtype),desc[i].dbsize,desc[i].scale); } userlog("%s\n",fdbuf); return(len);}/********************************************************************//* 函数: ConvertDBType *//* 用途: 转换数据类型代码 *//* 原型: char ConvertDBType(sb2 dbtype); *//* 参数: dbtype -- SQL Server返回的数据类型 *//* 返回: 用于发送的数据类型 *//********************************************************************/char ConvertDBType(sb2 dbtype){ switch(dbtype) { case(VARCHAR2_TYPE): /* VARCHAR2,STRING==>DBTYPE_STRING */ case(STRING_TYPE): return(DBTYPE_STRING); case(INT_TYPE): /* INT_TYPE ==>DBTYPE_INT */ return(DBTYPE_INT); case(NUMBER_TYPE): /* NUMBER_TYPE,FLOAT_TYPE==>DBTYPE_FLOAT */ case(FLOAT_TYPE): return(DBTYPE_FLOAT); case(ROWID_TYPE): /* ROWID_TYPE ==>DBTYPE_STRING */ return(DBTYPE_STRING); /* 可能有问题 */ case(DATE_TYPE): /* DATE_TYPE ==>DBTYPE_DATE */ return(DBTYPE_DATE); default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -