用高级语言实现select语句的功能

 用高级语言实现select语句的功能数据结构的课程设计:

用高级语言实现select语句的功能

SELECT [ALL|DISTINCT] <属性表达式>[,<属性表达式>…]

FROM <表名或视图名>[,<表名或视图名>…]

[WHERE <条件>] [GROUP BY <属性1>

[HAVING<条件>]] [ORDER BY <属性2> [ASC|DEC]

要求: (1) 能够以命令方式执行;

 (2) 能够以程序方式执行;

我选用比较熟练的c愿意完成了单表单条件(只支持关系条件):

SELECT [ALL|*] <属性名>[,<属性名>…]

FROM <表名>

[WHERE <关系条件>]

可以直接数据select语句进行查询如: select NO,NAME from stu where AGE>33

支持select语句换行书写,只需在行末尾加上分号,如:

select NO,NAME,AGE;

from stu;

where AGE>=33

 

 

 

支持程序方式运行,即执行一个文件中的select语句,如:

do sel.sql

其中sel.sql文件中内容如下:

select NO,NAME,AGE from stu where AGE>=33

退出命令是:quit

代码如下:

 

/*程序中用到的结构体dbf_head.h*/

#include<stdio.h>
#include<malloc.h>
#include <string.h>
#include "dbf_head.h"
//#define p(t) printf("debug_int%d/t./n",t)
//#define pc(c) printf("debug_char%c/t/n",c)
/*
 *query the SQL string user input
 */
char * query(char[]);
/*
 * equals "quit" ? if equals return 0
 */
  int isQuit(char[]);
  void pack(char *str);
  /*get where type*/
  int getWhereType(char *tmp);
  /*
  *check the table file
  */
  int check( Head_Table head, char attribute[][20],int *count_att, char *where1);
 

int compare(char *w1,char *w2,int type,char c);
  /**dfdfd*/
//void whereDisplay(FILE *fp,Head_Table head,int count_att,int wType,char *w1,char *w2);
  /*display the result of select*/
  void display(FILE *fp,Head_Table head,int count_att);
/*
 * open file
 */
 
  int openFile(char *name,FILE **fp)  ;
 /*
 *get_fields
 */
 void get_fields(FILE *fp, Head_Table *table);
/*
 * main, later we'll set the parameters to set the path of table;
 */


void pack(char *str){
    char *tmp,*p;

    int i=0,len=strlen(str);
    p=tmp=(char*)malloc(len);
   
    while(i<len){//跳过首部空格
       if(str[i]==' ')
        i++;
        else break;
    }
    while(i<len){
       if(str[i]!=' '&&str[i]!=','){
            *p++=str[i++];
        }else if(*(p-1)==' '||*(p-1)==',')
                i++;
             else *p++=str[i++];
    }
    if(*(p-1)==' '||*(p-1)==',')*(p-1)=0;
    else*p=0;
    strcpy(str,tmp);
    //strupr(str);

 }

 

int isDoSQL(char *str){
    char doS[4];
    doS[0]=*str;
    doS[1]=*(str+1);
    doS[2]=*(str+2);
    doS[3]=0;
    strupr(doS);
    return strcmp(doS,"DO ");
 }
/*程序方式执行:执行一个文件内的命令语句*/
int doSQL(char *str){
    FILE *fp;
    int i=2,j=0;
    int len;
    char name[80];
    char c;

     len=strlen(str);
     while(i<len&&str[i]==' ')i++;
     while(i<len&&str[i]!=' '){
        name[j++]=str[i++];
      }
      name[j]=0;

      if((fp=fopen(name,"r"))==NULL){
        printf("ERROR:Can not open the file %s/n",name);
        return 0;
      }
      j=0;
      c=fgetc(fp);
      while(c!=-1){

        if(c=='/n')
            c=' ';
        name[j++]=c;
        c=fgetc(fp);
      }
      name[j]=0;
      puts(name);
      query(name);
      return 1;

    

 }
 
 
 void whereDisplay(FILE *fp,Head_Table head,int count_att,int wType,char *w1,char *w2){
       Record_field *tmp;
       Data_tmp result[head.num_records][count_att];
        char c;
        int i,j=0,k=0,cc=0;
         int pp=0,wlen;
        char *buffer;
    fseek(fp,head.num_header+1,0);
    /**************/
     tmp=head.first;
      while(tmp){
            if(tmp->isWhere){
                buffer=(char *)malloc(tmp->len+1);
                c=tmp->type;
                break;
            }
            else{
                    pp+=tmp->len;
                    tmp=tmp->next;
            }
        }
        wlen=tmp->len;
  /***************************/

    while(k<head.num_records){
        ++k;
        tmp=head.first;

         /*8888888888888888888******/
        fseek(fp,pp,SEEK_CUR);
        fread(buffer,wlen,1,fp);
        i=wlen-1;
        buffer[wlen]=0;
        while(buffer[i]==0x20)buffer[i--]=0; //消除字符串后的空格
        fseek(fp,(-pp-wlen),SEEK_CUR);
        if(compare(buffer,w2,wType,c)){
            j=0;
            while(tmp){
                if(tmp->isShow){
                    if((result[cc][j].data=(char*) malloc(tmp->len+1))==NULL){
                        puts("ERROR: momery empty");
                        exit(0);
                    }
                    result[cc][j].type=tmp->type;
                    result[cc][j].len=tmp->len;

                    fread(result[cc][j].data,tmp->len,1,fp);
                    result[cc][j].data[tmp->len]=0;

                    j++;
                }else{
                    fseek(fp,tmp->len,SEEK_CUR);
                }
                tmp=tmp->next;
            }
            fseek(fp,1L,SEEK_CUR);
             cc++;
        }else{
           fseek(fp,head.num_record,SEEK_CUR);
        }
       
        }
     printf("--------------------------results of query(%d,%d)--------------------------------/n",cc,j);
     if(j==0)cc=0;
    tmp=head.first;
    while(tmp){
        if(tmp->isShow)
            printf("%s/t",tmp->name);
        tmp=tmp->next;
    }
    printf("/n");
    for(k=0;k<cc;k++){
        for(i=0;i<j;i++){
            if(result[k][i].type=='I'){
                pp=0;
                pp=(int)result[k][i].data[0];
                pp=pp|((int)result[k][i].data[1]<<8);
                pp=pp|((int)result[k][i].data[2]<<16);
                pp=pp|((int)result[k][i].data[3]<<16) ;
                printf("%d/t",pp);
            }
            else
             printf("%s/t",(result[k][i].data));
        }

        puts("");
    }
    puts("----------------------------------query ended----------------------------------");
}


int compare(char w1[],char w2[],int type,char c){

    int p1,p2=0;
    int i;
    if(c=='I'){
       p1=(int)w1[0];
       p1=p1|((int)w1[1]<<8);
       p1=p1|((int)w1[2]<<16);
       p1=p1|((int)w1[3]<<16) ;

       i=0;
        while(w2[i]){
            p2=(p2+(w2[i]-0x30))*10;
            i++;
        }
        p2=p2/10;

       switch(type){
        case 1: return (p1<=p2);
        case 2:return (p1>=p2);
        case 3:return (p1!=p2);
        case 4:return (p1!=p2);
        case 5:return (p1>=p2);
        case 6:return (p1<=p2);
        case 7:return (p1==p2);
        case 8:return (p1<p2);
        case 9:return (p1 > p2);
        default : return 0;
       }
    }else{

        i=strcmp(w1,w2);
        switch(type){
        case 1:  i=(i<=0?1:0); break;
        case 2: i=(i>=0?1:0);  break;
        case 3: i;break;
        case 4: i;    break;
        case 5:i= (i>=0?1:0);  break;
        case 6: i= (i<=0?1:0);  break;
        case 7: i=!i;    break;
        case 8: i=(i<0?1:0);  break;
        case 9: i=(i>0?1:0);  break;
        default : i=-1;
       }

       return i;
    }
}

 
void main(void){
 char para[100]={0};
 char c;
 int i=0;
 while(1){
  c = getchar();
  if(c ==';'){
   c = getchar();
   if(c=='/n')
    c =' ';
   else{
        para[i++]=' ';
   }
  }
  if(c =='/n'){
     para[i]=0;
     pack(para);
  
     if(isQuit(para)==0)
   exit(0);
   if(isDoSQL(para)==0){
          doSQL(para);
          i=0;
          continue;
                }
   
   
     query(para);
     i=0;
     continue;
  }
  para[i++]=c;
 }
}
char * query(char* string){/*要求string为“紧缩”格式*/
    int len_str = strlen(string);
    char tmp[30]={0};
    char attribute[20][20]={0};
    char table[10]={0};
    char where1[20]={0};
    char where2[20]={0};
    int  whereType=0;
    FILE *file=NULL;
    int i,j,count_att;
    Head_Table head = {0,0,0,NULL};
 //puts("********Here is query ********");

    i=0;
    while(i<6&&i<len_str){
        tmp[i]=string[i];
        i++;
    }
    tmp[6]=0;
    strlwr(tmp);
    if(strcmp(tmp,"select")==0){
       /*将select之后的属性读入数组***********************************/
       count_att=0;
       ++i;

       while(1){
           j=0;
           while(string[i]!=','&&string[i]!=' '&&i<len_str){
           tmp[j++]=string[i++];
           }
           if(i>=len_str){puts("Error: bad command!");return NULL;}
           i++;
           tmp[j]=0;
           if(strcmp(tmp,"from")!=0){
                strcpy(attribute[count_att],tmp);

                count_att++;
           }else break;
       }/*end while*/
       /*将from之后的表名读入数组*/
       j=0;

       while(string[i]==' ')i++;
       while(string[i]!=','&&string[i]!=' '&&i<len_str){
           tmp[j++]=string[i++];
       }
       tmp[j]=0;
       strcpy(table,tmp);

       /***读取where子句**************************************/
       j=0;
       while(string[i]==' ')i++;
       while(string[i]!=','&&string[i]!=' '&&i<len_str){
           tmp[j++]=string[i++];
       }
       tmp[j]=0;
       if(strcmp(tmp,"where")==0){

            /***********************/
            j=0;
            while(string[i]==' ')i++;
            while(string[i]!='='&&string[i]!='<'&&string[i]!='>'&&string[i]!='!'&&string[i]!=' '&&i<len_str)
            where1[j++]=string[i++];
            where1[j]=0;

            j=0;
            tmp[j++]=string[i++];
            if(string[i]=='='||string[i]=='>'||string[i]=='<'){
                tmp[j++]=string[i++];
            }
            tmp[j]=0;

            whereType=getWhereType(tmp);
            /***********************/
            j=0;
            while(string[i]==' ')i++;
            while(string[i]!='='&&string[i]!='<'&&string[i]!='>'&&string[i]!='!'&&string[i]!=' '&&i<len_str)
            where2[j++]=string[i++];
            where2[j]=0;

        }else if(strlen(tmp)!=0){
                puts("ERROR: Unknow command!");
                return NULL;
            }
       /***open table ******************************************/

        if(openFile(table,&file)==0){
            puts("/nError: can not open the table!");
            return NULL;
        }
        /**********读取表文件的字段******************/
        rewind(file);
 
        get_fields(file,&head);
        if(!check(head,attribute,&count_att,where1)){puts("Error:check");return NULL;}
        /************开始查询了***************/
        if(whereType==0){
            display(file,head,count_att);
        }else{
            whereDisplay(file,head,count_att,whereType,where1,where2);
        }

    }else{
        puts("no select command/n");
    }
    if(file!=NULL)
        fclose(file);
 return string;
 }
int openFile(char *name,FILE **fp){
     char *filename;

     int len = strlen(name)+5;
     filename = (char*)malloc(sizeof(char)*len);
     strcpy(filename,name);
     filename[len-1]=0;
     filename[len-2]='f';
     filename[len-3]='b';
     filename[len-4]='d';
     filename[len-5]='.';

     *fp = fopen( filename,"rb");
     if(*fp ==NULL)return 0;
     /*Head_Table head={0,0,0,NULL};*/
     /*get_fields(fp,&head);*/
     free(filename);
     return 1;
 }
void get_fields(FILE *fp, Head_Table *table){
     FILE *ff=fp;
     struct Record_field *next,*tmp;
     int c;
     int i,j;
     fseek(fp,4,0);
     fread(&table->num_records,4,1,fp);
     fread(&table->num_header,2,1,fp);
     fread(&table->num_record,2,1,fp);

    if(!(next = (Record_field*)malloc(sizeof(Record_field))))exit(0);
    table->first = next;
    fseek(fp,32,0);
    c= fgetc(fp);
   /* printf("____: %d/n",ftell(fp));    */
    while(c!=13&&c!=-1){
        if(!(tmp = (Record_field*)malloc(sizeof(Record_field))))exit(0);
        tmp->name[0]=c;
        for(i=1;i<11;i++){ /* get the name of field */
           c= fgetc(fp);
           tmp->name[i]=c;
        }
        tmp->name[i]=0;
        c= fgetc(fp);       /* get the type of field */
        tmp->type=(char)c;
        fseek(fp,4,SEEK_CUR);
        c= fgetc(fp);       /* get the length of field */
        tmp->len=c;
        fseek(fp,14,SEEK_CUR);
        c= fgetc(fp);       /* field is part of production index - 0x01 else 0x00 */
        tmp->isIndex=c;
        next->next=tmp;
        next = tmp;
        c= fgetc(fp);
    }
        next = table->first;
        table->first=next->next;
        free(next);
        /*display the fields*/
        tmp = table->first;   /*
        while(tmp){
            printf("%s/t%c/t%d/t%d/n",tmp->name,tmp->type,tmp->len,tmp->isIndex);
            tmp=tmp->next;
        }           */
}
int getWhereType(char *tmp){
    if(strcmp(tmp,"<=")==0)
        return 1;
    if(strcmp(tmp,">=")==0)
        return 2;
    if(strcmp(tmp,"!=")==0)
        return 3;
    if(strcmp(tmp,"<>")==0)
        return 4;
    if(strcmp(tmp,"!<")==0)
        return 5;
    if(strcmp(tmp,"!>")==0)
        return 6;
    if(strcmp(tmp,"=")==0)
        return 7;
    if(strcmp(tmp,"<")==0)
        return 8;
    if(strcmp(tmp,">")==0)
        return 9;
}

/*查询并显示数据*/
void display(FILE *fp,Head_Table head,int count_att){
    Record_field *tmp;
    Data_tmp result[head.num_records][count_att];
    char c;
    int i,j=0,k=0,cc=0;
    int pp;
    fseek(fp,head.num_header+1,0);
    while(k<head.num_records){
        ++k;
        tmp=head.first;
        j=0;

        while(tmp){
            if(tmp->isShow){
                if((result[cc][j].data=(char*) malloc(tmp->len+1))==NULL){
                    puts("ERROR: momery empty");
                    exit(0);
                 }
                result[cc][j].type=tmp->type;
                result[cc][j].len=tmp->len;
                /*读取数据*/
                fread(result[cc][j].data,tmp->len,1,fp);
                result[cc][j].data[tmp->len]=0;
                j++;
            }else{
                fseek(fp,tmp->len,SEEK_CUR);

            }
            tmp=tmp->next;
        }
        fseek(fp,1L,SEEK_CUR);
         cc++;
    }


    printf("--------------------------results of query(%d,%d)--------------------------------/n",cc,j);
    if(j==0)cc=0;
    tmp=head.first;
    while(tmp){
        if(tmp->isShow)
            printf("%s/t",tmp->name);
        tmp=tmp->next;
    }
    printf("/n");
    for(k=0;k<cc;k++){
        for(i=0;i<j;i++)
        if(result[k][i].type=='I'){
                pp=0;
                pp=(int)result[k][i].data[0];
                pp=pp|((int)result[k][i].data[1]<<8);
                pp=pp|((int)result[k][i].data[2]<<16);
                pp=pp|((int)result[k][i].data[3]<<16) ;
                printf("%d/t",pp);
            }
            else
             printf("%s/t",(result[k][i].data));
        puts("");
    }
    puts("----------------------------------query ended----------------------------------");
}


int check(Head_Table head, char (*attribute)[20],int *count_att, char* where1){
    int i=0;
    Record_field *tmp=head.first;
    /*检测是否含有ALL或* */
    if(((strcmp(attribute[0],"*")==0)||(strcmp(attribute[0],"ALL")==0))&&attribute[1][0]==0){
         tmp=head.first;

         while((tmp!=NULL)){
            tmp->isShow=1;
            //strcpy(attribute[i++],tmp->name);
            tmp=tmp->next;
         }
         *count_att=head.num_records;

    }else{
        i=0;
       for(;i<*count_att;i++){
         tmp=head.first;
         while((tmp!=NULL)&&strcmp(attribute[i],tmp->name))tmp=tmp->next;
         if(tmp==NULL)continue;
            tmp->isShow=1;
        }

    }
    tmp=head.first;
         while((tmp!=NULL)&&strcmp(where1,tmp->name))tmp=tmp->next;
         if(tmp)
            tmp->isWhere=1;
    return 1;
 }

 int isQuit(char* str){
     char qS[5];
    qS[0]=*str;
    qS[1]=*(str+1);
    qS[2]=*(str+2);
    qS[3]=*(str+3);
    qS[4]=0;
    strupr(qS);
    return strcmp(qS,"QUIT");
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<script src="http://club.book.csdn.net/people/javascript/xinyu3911.js"></script>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值