📄 conv.c
字号:
/******************************************************************
Update by chenxu 2000-12-7
This file is to genarate SQL * loader file from DBF.
input : data control file.
output: data.txt, data.ctl, data.sql
Input file format__________________________________________________
#
#
[input]
dbf = /u1/xt170/ftpd/data/d-bdw11.dbf
[output]
txt = /u1/xt170/ftpd/data/d-bdw11.txt
sql = /u1/xt170/ftpd/data/d-bdw11.sql
ctl = /u1/xt170/ftpd/data/d-bdw11.ctl
[switch]
txt = on
sql = on
ctl = on
#
#
******************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#define MAX_ROW_LENGTH 1200
#define MAX_FIELD_NUMBER 100
typedef struct head /* dbf头文件结构 */
{
unsigned char mask ;
unsigned char date[3] ;
unsigned long record_num;
unsigned short int head_length;
unsigned short int field_length ;
} HEAD ;
typedef struct field /* dbf字段结构 */
{
unsigned char name[11];
unsigned char type ;
unsigned long add;
unsigned char length;
unsigned char dec ;
} FIELD ;
/*************************************************************
Function: Trim()
删除字符串前后的空格
*************************************************************/
void trim(char * str, char * output)
{ char ret[120];
int len;
strcpy(ret ,str);
while (ret[0] == ' ')
{
strcpy(ret, &ret[1]); //去前面的空格
};
len = strlen(ret);
while(ret[len-1]==' ') //去后面的空格
{
ret[len-1]='\0';
len = strlen(ret);
};
strcpy(output, ret);
return;
}
/*************************************************************
Function: upstring()
将字符串转换成大写
*************************************************************/
void upstring(char * str, char * output)
{
char tmpstr[255];
int len,i;
strcpy(tmpstr, str);
len = strlen(tmpstr);
for (i=0; i<len; i++) {
if (isalpha(tmpstr[i])!=0) {
tmpstr[i] = toupper(tmpstr[i]);
}
}
strcpy(output,tmpstr);
}
/*************************************************************
Function: ProfileString()
从控制文件filename中,读取heading标题下,key项目的值。
*************************************************************/
void ProfileString(char * filename, char * heading, char * key, char * value)
{
FILE * fp;
char file[80];
char sValue[120];
char filestr[120],tmpstr[120];
int len = 120;
char * sp;
strcpy(sValue, "");
strcpy(file, filename);
if((fp = fopen(file, "r+")) ==NULL) {
printf("\nCan't open data control file:%s\n", file);
exit;
}
do
{
if (fgets(filestr,120,fp)==NULL) break; //读控制文件的一行到filestr
if (filestr ==NULL) break;
trim(filestr, tmpstr); //去掉首尾空格
strcpy(filestr, tmpstr);
if (filestr[0] == '[' ) { //标题行
if (strstr(filestr, heading)!=NULL){ //且正好是heading所指标题行
do{
if (fgets(filestr,120,fp)==NULL) break ; //下一行
if ((filestr ==NULL)||(filestr[0] == '[')) break;
trim(filestr, tmpstr); //去掉首尾空格
strcpy(filestr, tmpstr);
if ((sp=strstr(filestr, key))!=NULL){
if (sp -filestr ==0 ) { //找到相关key
sp = strchr(filestr, '=');
if (sp != NULL ) { //找到了key值
strcpy(sValue, sp+1);
//sValue还可能包含回车符,也必须去掉
fclose(fp);
sp = strchr(sValue, '\n');
if (sp !=NULL) {
sValue[sp-sValue]='\0';
}
trim(sValue, sValue);
strcpy(value ,sValue);
return;
}
}
}
}while (filestr != NULL && filestr[0] != '[');
}
}
} while (filestr != NULL);
fclose(fp);
sp = strchr(sValue, '\n');
if (sp !=NULL) {
sValue[sp-sValue]='\0';
}
trim(sValue, sValue);
strcpy(value ,sValue);
}
int main(int argc,char **argv){
char buf[MAX_ROW_LENGTH];
unsigned field_num;
unsigned long i;
char dbf[80],dbfname[80],out_txt[80], out_sql[80], out_ctl[80];
char txt_sw[10],sql_sw[10], ctl_sw[10], control[80];
HEAD *dbfhead ;
HEAD myhead;
FIELD dbffield[MAX_FIELD_NUMBER];
FILE *fout, *fp;
int prog_debug = 0;
if (argc!=2)
{
printf("\nUsage : load <DATA CONTROL FILE>\n") ;
return -1;
}
strcpy(control, argv[1]);
//strcpy(control, "c:\\170\\c\\load\\data.ctl");
//读取配置文件
ProfileString(control, "input", "dbf", dbf);
ProfileString(control, "output", "txt", out_txt);
ProfileString(control, "output", "sql", out_sql);
ProfileString(control, "output", "ctl", out_ctl);
ProfileString(control, "switch", "txt", txt_sw);
ProfileString(control, "switch", "sql", sql_sw);
ProfileString(control, "switch", "ctl", ctl_sw);
strcpy(dbfname, dbf);
dbfname[strlen(dbf) -strlen(".dbf")] = '\0';
dbfhead = &myhead;
strcpy(buf,"");
if ((fp=fopen(dbf,"rb")) == NULL)
{
printf("Cannot open file %s\n", dbf);
return -1 ;
}
fseek(fp,0,SEEK_SET);
fread(dbfhead,sizeof(HEAD),1,fp); //读dbf头文件信息
field_num = (dbfhead->head_length-1)/32 -1 ; // 字段个数
if (prog_debug) printf("\nRead DBF : field numbers =%d, record num =%ld", field_num, dbfhead->record_num);
/*typedef struct field
{
unsigned char name[11];
unsigned char type ;
unsigned long add;
unsigned char length;
unsigned char dec ;
} FIELD ;
*/
for( i=0; i< field_num; i++)
{
fseek(fp,32*(i+1),SEEK_SET);
fread(&dbffield[i],sizeof(FIELD),1,fp); // 读dbf结构信息
if (prog_debug) {
printf("\nDBF field %d struct:",i);
printf("\nname = [%s]",dbffield[i].name);
printf("\ntype = [%c]",dbffield[i].type);
printf("\nadd = [%ld]",dbffield[i].add);
printf("\nlength = [%d]",dbffield[i].length);
printf("\ndec = [%d]",dbffield[i].dec);
}
}
// 输出控制文件 ******************************************************
if (strcmp(ctl_sw, "on")==0) {
printf("\nGenerate CTL ....");
if ((fout=fopen(out_ctl,"w")) == NULL)
{
printf("Cannot open file %s\n", out_ctl);
return -1 ;
}
fprintf(fout,"LOAD DATA\n");
fprintf(fout,"INFILE '%s'\n", out_txt);
fprintf(fout,"INTO TABLE %s (\n", dbfname);
for(i=0;i< field_num;++i)
{ fprintf(fout, "%11s POSITION(%d:%d)", dbffield[i].name,
dbffield[i].add, dbffield[i].add + dbffield[i].length -1 );
switch (dbffield[i].type) {
case 'C':
case 'L': // 字符型/ 逻辑型
fprintf(fout, " CHAR");
break ;
case 'N':
if (dbffield[i].dec == 0 ) // 整数型
fprintf(fout, "INTEGER EXTERNAL NULLIF %s = BLANKS",dbffield[i].name);
else //实数型
fprintf(fout, " DECIMAL EXTERNAL NULLIF %s =BLANKS",dbffield[i].name );
break;
case 'D': // 日期型
fprintf(fout, " DATE 'YYYYMMDD' NULLIF %s = BLANKS", dbffield[i].name);
break;
default:
break;
}
if(i< field_num -1)
fprintf(fout, ",\n") ;
}
fprintf(fout, ")\n");
fclose(fout);
}
// 产 生CREATE TABEL. 的SQL 语 句 ***********************************************
if (strcmp(sql_sw, "on")==0) {
printf("\nGenerate SQL ....");
if ((fout=fopen(out_sql,"w")) == NULL)
{
printf("Cannot open file %s\n",out_sql);
return -1 ;
}
fprintf(fout, "create table %s (\n", dbfname);
for(i=0;i< field_num;i++)
{
fprintf(fout,"%11s",dbffield[i].name);
switch (dbffield[i].type){
case 'C': // 字符型 //
fprintf(fout, " CHAR(%d)",dbffield[i].length);
break;
case 'L': // 逻辑型 //
fprintf(fout, " CHAR(1)");
break;
case 'N': // 数字型
if (dbffield[i].dec==0)
fprintf(fout," NUMBER(%d)", dbffield[i].length) ;
else
fprintf(fout, " NUMBER(%d,%d)",
dbffield[i].length-1, dbffield[i].dec);
break;
case 'D': // 日 期 型
fprintf(fout, " DATE");;
break;
default:
break;
}
if (i< field_num - 1) fprintf(fout, ",\n");
}
fprintf(fout, ")\n");
fclose(fout);
}
// 产生SQL*Loader数据文件 **********************************************
if (strcmp(txt_sw, "on")==0) {
printf("\nGenerate TXT ....\n");
if((fout=fopen(out_txt,"w")) == NULL)
{
printf("Cannot open file %s\n", out_txt);
return -1 ;
}
fseek(fp,dbfhead->head_length,SEEK_SET);
// append a serno data to record
for(i=0;i< dbfhead->record_num;i++)
{
fread(buf,dbfhead->field_length,1,fp);
buf[dbfhead->field_length] ='\0';
fprintf(fout,"%s%ld\n", buf+1,i+1); //skip记录首字节(删除标志)
}
fclose(fout);
fclose(fp);
}
//***************************************************************************
return 0 ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -