《数据库系统课程设计》

一、课程设计的性质和目的

《数据库系统课程设计》是一门实践性课程,要求学生在教师的指导下,充分利用所学的数据库、数据结构、C/C++语言等相关知识,从底层做起,实现数据库的组织、存储、检索、更新和索引等功能。目的是让学生深刻理解关系数据库系统中数据和元数据的组织方式、存储方式、检索方式、更新方式和索引方式,同时培养学生的逻辑思维能力和锻炼学生的动手编程能力。

二、课程设计教学基本内容和要求

课程设计教学基本内容
(1)设计特定的数据结构,用于存储数据表、视图、索引等数据库对象的信息,即建立数据库系统的数据字典;
(2)设计特定的数据结构,用于存储数据表中的数据;
(3)设计特定的数据结构,用于存储索引数据;
(4)设计特定的数据结构,分别用于存储用户和访问权限的信息;
(5)输入“help database”命令,输出所有数据表、视图和索引的信息,同时显示其对象类型;输入“help table 表名”命令,输出数据表中所有属性的详细信息;输入“help view 视图名”命令,输出视图的定义语句;输入“help index 索引名”命令,输出索引的详细信息;
(6)解析CREATE、SELECT、INSERT、DELETE、UPDATE等SQL语句的内容;
(7)检查SQL语句中的语法错误和语义错误;
(8)执行CREATE语句,创建数据表、视图、索引等数据库对象;创建数据表时需要包含主码、外码、唯一性约束、非空约束等完整性约束的定义;
(9)执行SELECT语句,从自主设计的数据表中查询数据,并输出结果;在SELECT语句中需要支持GROUP BY、HAVING和ORDER BY子句,需要支持5种聚集函数;
(10)执行INSERT、DELETE和UPDATE语句,更新数据表的内容;更新过程中需要检查更新后的数据表是否会违反参照完整性约束。如果是,则提示违反哪一条完整性约束,并拒绝执行更新操作;如果否,提示数据表更新成功,并说明插入、删除或修改了几个元组。
(11)当数据表的内容更新后,根据索引的定义,自动更新索引表的内容;
(12)在有索引的数据表上执行查询语句时,首先利用索引找到满足条件的元组指针,然后通过指针到数据表中取出相应的元组;
(13)执行GRANT语句,为用户授予SELECT、INSERT、DELETE、UPDATE权限;执行REVOKE语句,收回上述权限;
(14)用户登录时,需要输入用户名;如果用户没有被授权,则拒绝执行用户查询或更新操作,并给出提示信息;
(15)将SELECT语句转化为关系代数表达式,再利用查询优化算法对关系代数表达式进行优化,输出优化后的关系代数表达式或SELECT语句。

三、课程设计报告要求

(1)课程设计报告采用山东科技大学印刷的“课程设计说明书”;
(2)在课程设计任务书中,应说明课程设计题目(自己拟定)、设计原始资料和主要解决问题;
(3)报告内容应当包括设计要求、需求分析、设计思想、程序流程图、主要源程序、运行结果、参考资料、总结等部分。

数据库系统课程设计报告

课程设计报告内容

3.1系统功能设定

该系统提供了几大功能分别是创建数据表的(create table)、显示数据和数据库的属性信息(输入“help database”命令,输出所有数据表、视图和索引的信息,同时显示其对象类型;输入“help table 表名”命令,输出数据表中所有属性的详细信息,包括属性名称、数据类型、约束条件等;输入“help view 视图名”命令,输出视图的定义语句;输入“help index 索引名”命令,输出索引的详细信息)、向指定的表中插入数据(insert)、删除指定表中的数据(delete)、更新指定表中的数据(update)、查询指定表中按条件查询和显示查询结果(select)、创建视图(create view)、创建索引(create index)、对用户对各个表的权限的操作:授权(grant)和回收权限(revoke),对于有超级管理员权限用户还提供新建用户、删除用户和查看所有用户密码的功能。
3.2系统软件介绍
该系统软件进入后首显示该系统提供的功能,该系统默认有个root用户(超级管理员用户),密码为:123;用户首先通过root用户登录系统,登录之后可以建立用户,给用户授予不同的权限。然后可以通过新建的用户登录系统,根据系统提供的功能输入SQL语句进行相应的操作,其中操作主要包括表的建立(create table)、向表中插入数据(insert into )、对表中的数据进行更新(update )、按条件删除表中的数据(delete )、根据查询条件查询选择表中的数据(select )、还可将该表的select、insert、update、delete等权限授予某系用户(grant )、也可以通过(revoke )收回某些用户对该表的select、insert、update、delete等权限、还可以对该表建立视图(create view )和建立某个属性的索引(create index )。其中对表进行选择(select)、更新数据(update)、删除数据(delete)支持and、or和between and 的组合命令,对于建表(create table)支持约束条件的定义并且对表执行insert操作时会检查是否破坏了该表的约束条件;该系统还会解析CREATE、SELECT、INSERT、DELETE、UPDATE等SQL语句,检查SQL语句中的语法错误和语义错误,并指出错误原因;对于超级管理员对于所有操作都没有限制,还有一些特权操作:创建新用户、删除某个用户和查看当前系统中的所有用户和密码。该系统软件的所有数据都通过文件存储在磁盘中,通过设计的特定的数据结构管理数据库中的表、视图和索引,并且对用户的权限(包括用户的创建、插入、更新、删除、选择权限和每个用户对数据库对象中的每个表的操作权限)用一个特定的数据结构进行管理;系统软件运行时,首先按指定的目录加载系统的用户信息然后在更具指定的路径加载数据库中的对象信息(存在的表、视图和索引等),并将这些所有的加载的信息分别用为它们特意设计的对应数据结构来记录它们。如果系统软件在运行中有数据的更新、插入等操作对数据库进行了修改会将它们对应的在磁盘中的存储文件做相对应的修改。

3.2.1系统软件流程

在这里插入图片描述

Help模块包括“help database”,输出所有数据表、视图和索引的信息,同时显示其对象类型;“help table 表名”,输出数据表中所有属性的详细信息,包括属性名称、数据类型、约束条件等;“help view 视图名”,输出视图的定义语句;“help index 索引名”,输出索引的详细信息,并且会分析语法和语义错误并反馈回来是什么错误。
Create table模块主要完成一个表的建立,包括表的属性名、属性类型和约束条件,并且会分析语法和语义错误并反馈回来是什么错误。
Create index模块完成根据命令中指定的属性建立索引表,并且会分析语法和语义错误并反馈回来是什么错误。
Create view模块完成根据用户输入的命令建议一个文件选择命令的原形,当对视图进行操作时再见该命令一起嵌入执行,并且会分析语法和语义错误并反馈回来是什么错误。
Insert模块主要完成指定表的数据插入,在插入的过程会检查是否破坏约束条件和类型是否匹配,字段数是否匹配等,看是否重复插入,并且会分析语法和语义错误并反馈回来是什么错误。
Update模块主要完成指定表中某事数据的更新,并且该更新后是否合法,支持and、or和between and和随机组合逻辑运算,并且会分析语法和语义错误并反馈回来是什么错误。
Select模块完成主要完成根据指定的条件来选择指定表中的记录,并将该记录中指定的属性列显示出来;where中支持and、or和between and的随机组合逻辑运算,并且会分析语法和语义错误并反馈回来是什么错误。
Grant模块,执行GRANT语句,为用户授予对某数据库对象的SELECT、INSERT、DELETE、UPDATE等权限,并且会分析语法和语义错误并反馈回来是什么错误。
Revoke模块,执行REVOKE语句,收回用户对某数据库对象的SELECT、INSERT、DELETE、UPDATE等权限,并且会分析语法和语义错误并反馈回来是什么错误。

3.2.2 help命令的实现和显示

在这里插入图片描述
主要代码:

//help模块显示
void My_help(string op, int &flag)
{

	//help database命令输出所有数据表、视图和索引的信息,同时显示其对象类型;
	if (op == "help database")
	{
		int have = 0;
		flag = 1;
		//输出表
		for (int i = 0; i < table.size(); ++i)
		{
			have = 1;
			cout << "\n===============================\n";
			
			cout << "----distable:" << table[i].table_name << " 的属性----" << endl;
			for (int j = 0; j < table[i].ziduanName.size(); ++j)//显示对象
				cout << table[i].ziduanName[j] << "   ";
			cout << endl;
			for (int j = 0; j < table[i].ziduanName.size(); ++j)//显示对象类型
				cout << table[i].type_value[j] << " ";
			cout << endl;
			cout << "_______________________________\n" << endl;
		}
		
		//输出视图
		for (int i = 0; i < view.size(); ++i)
		{
			have = 1;
			cout << "\n===============================\n";
			cout << "----disview:" << view[i].view_name << " 的属性----" << endl;
			cout << "create view " << view[i].view_name << endl;
			for (int j = 0; j < view[i].codes.size(); ++j)
				cout << view[i].codes[j] << endl;
			cout << endl;
			cout << "_______________________________\n" << endl;
		}
		
		//输出索引
		for (int i = 0; i < index.size(); ++i)
		{
			have = 1;
			cout << "\n===============================\n";
			cout << "----disindex:" << index[i].index_name << " 的属性----" << endl;
			cout << "create index " << index[i].index_name << endl;
			for (int j = 0; j < index[i].code.size(); ++j)
				cout << index[i].code[j] << endl;
			cout << endl;
			cout << "_______________________________\n" << endl;
		}
		

		if (have == 0) cout << "\n【该数据库中暂无数据!】\n" << endl;

		return;
	}

	//输入help table 表名命令,输出数据表中所有属性的详细信息;
	string s = "help table ";
	int f = 1;
	for (int i = 0; i < s.length(); ++i)
	{
		//判断输入的命令是否是help table
		if (op[i] != s[i])
		{
			f = 0;
			break;
		}
	}
	if (f == 1)
	{
		flag = 1;
		string name;
		for (int j = s.length(); j < op.length(); ++j)
			name += op[j];
		int ff = 0;
		for (int k = 0; k < table.size(); ++k)
		{
			if (table[k].table_name == name)
			{
				cout << "\n===============================\n";
				cout << "---- distable:" << table[k].table_name << "的数据----" << endl;
				cout << "_________________________\n" << endl;

				ifstream fin;
				string tt = "..\\" + table[k].table_name + ".txt";
				char file[30];
				for (int i = 0; i < tt.length(); ++i)
					file[i] = tt[i];
				file[tt.length()] = '\0';
				fin.open(file);
				string t;
				while (getline(fin, t))
					if (t != "")
						cout << t << endl;
				cout << endl;
				ff = 1;
				cout << "_________________________\n" << endl;
				return;
			}
		}
		if (!ff) cout <<"【 [" <<  name << "] 表不存在!】\n" << endl;
		return;
	}

	//输入“help view 视图名”命令,输出视图的定义语句;
	s = "help view ";
	f = 1;
	for (int i = 0; i < s.length(); ++i)
	{
		if (op[i] != s[i])
		{
			f = 0;
			break;
		}
	}
	if (f == 1)
	{
		flag = 1;
		string name;
		for (int j = s.length(); j < op.length(); ++j)
			name += op[j];
		int ff = 0;
		for (int k = 0; k < view.size(); ++k)
		{
			if (view[k].view_name == name)
			{
				cout << "\n===============================\n";
				cout << "---- disview:" << view[k].view_name << " ----" << endl;
				cout << "__________________" << endl;
				cout << "create view " << name << endl;
				for (int j = 0; j < view[k].codes.size(); ++j)
					cout << view[k].codes[j] << endl;
				cout << endl;
				ff = 1;
				cout << "__________________\n" << endl;
				return;
			}
		}
		if (!ff) cout << "【 [" << name << "] 视图不存在!】\n" << endl;
		return;
	}

	//输入“help index 索引名”命令,输出索引的详细信息;
	s = "help index ";
	f = 1;
	for (int i = 0; i < s.length(); ++i)
	{
		if (op[i] != s[i])
		{
			f = 0;
			break;
		}
	}
	if (f == 1)
	{
		flag = 1;
		string name;
		for (int j = s.length(); j < op.length(); ++j)
			name += op[j];
		int ff = 0;
		for (int k = 0; k < index.size(); ++k)
		{
			if (index[k].index_name == name)
			{
				cout << "\n===============================\n";
				cout << "---- disindex:" << index[k].index_name << " ----" << endl;
				cout << "__________________" << endl;
				cout << "create index " << name << endl;
				for (int j = 0; j < index[k].code.size(); ++j)
					cout << index[k].code[j] << endl;
				cout << endl;
				ff = 1;
				cout << "__________________\n" << endl;
				return;
			}
		}
		if (!ff) cout << "【 [" << name << "] 索引不存在!】\n" << endl;
		return;
	}
}

该不分只要是通过三个结构体向量的遍历,其一是vector

table;//用TABLE类定义一个table向量,类似于table数组,里面的元素均为表,其二是vector view;//用VIEW类定义一个view向量,类似于view数组,里面的元素均为视图信息,其三是vector index;用INDEX类定义一个index向量,类似于index数组,里面的元素均为索引信息。

3.2.3表的建立与存储

在这里插入图片描述
主要代码

class TABLE
{
public:
	string table_name;//表名
	vector<string> ziduanName;//字段名
	vector<string> type_value;//字段类型名·
	/***************************
		0: 无约束条件
		1: primary key
		2: unique
		3: not null
    **************************/
	vector<int> condition;  //约束条件
	int shuxing_count;//属性个数
	int remcount = 0;//元组个数
};

vector<TABLE> table;//用TABLE类定义一个table向量,类似于table数组,里面的元素均为表

定义一个表的结构体,用于存放表的信息包括表名、字段名、字段类型名、约束条件、属性个数、元祖个数等。

//表的建立和存储
void My_create_table(string op, int &flag, string str)
{

	string s = "create table ";
	int f = 1;
	for (int i = 0; i < s.length(); ++i)
	{
		if (op[i] != s[i])
		{
			f = 0;
			break;
		}
	}
	if (f)
	{
		if (str == "false")
		{
			while (getline(cin, s) && s != ")");
			cout << "该用户没有创建表的权限" << endl;
			return;
		}
		flag = 2;

		TABLE t;
		t.shuxing_count = 0;
		int flag;
		int f1 = 0;
		int f2 = 0;
		string _str = "\n";

		string tmp = "create table ";
		int k = tmp.length();
		//获取表的名字
		string __name;
		t.table_name = "";
		for (; (op[k] != '\n' || op[k] != '(' || op[k] != ' ') && k < op.length(); ++k)
			__name += op[k];

		for (vector<TABLE>::iterator it = table.begin(); it != table.end(); it++){
			if (it->table_name == __name){
				//while (getline(cin, s) && s != ")");
				_str = _str + "【" + __name + " 表已存在】\n";
				f1++;
			}
		}
		if (f1 == 0)
		{
			t.table_name = __name;
		}

		//获取表中字段名及字段类型
		string s;
		while (getline(cin, s) && s != ")" )//只有回车会终止getline操作,每次回车进行一次循环,到出现)终止
		{
			t.shuxing_count++;
			int f = 1;
			int i = 0;
			tmp = "";
			//输入一个字符串,计算其长度

			while (!((s[i] >= 'a'&&s[i] <= 'z') || (s[i] >= 'A'&&s[i] <= 'Z')))//防止在第二行开头出现(或者空格的情况导致无法建表
				++i;

			for (; s[i] != ' ' && i < s.length(); ++i)//将该字符串即字段名存下来
			{
				tmp += s[i];
			}

			if (tmp.length() == 0)
			{
				while (getline(cin, s) && s != ")");
				cout << "create 语法错误!" << endl;
				return;
			}

			int m = 0;
			tmp = "";

			while (!((s[i] >= 'a'&&s[i] <= 'z') || (s[i] >= 'A'&&s[i] <= 'Z')))//防止字段名和字段类型中间空格个数不可控
				++i;

			for (; s[i] != '(' && s[i] != ' '&& s[i] != ',' && i < s.length(); ++i)//将该字符串即字段类型存下来
			{
				tmp += s[i];
				// m=i;
			}

			//判断字段类型是否正确
			if ((tmp != "char") && (tmp != "int") && (tmp != "float") && (tmp != "double") && (tmp != "time") && (tmp != "date"))
			{
				_str = _str + " " + tmp + " 字段类型错误!\n";
				f1++;
			}

			if (tmp.length() == 0)
			{
				while (getline(cin, s) && s != ")");
				cout << "create 语法错误!" << endl;
				return;
			}

			//去除了结尾的逗号,以及第二行开始的(,全都变成空格
			for (int i = 0; i < s.length(); i++)
			if (s[i] == ',')
				s[i] = ' ';
			if (s[0] == '(')
				s[0] = ' ';

			//如果加约束的话,因为约束不是一个字符串,所以不能像之前的挨个字符串判断,在判断前两个字符串是否符合字段名和字段类型之后,
			//然后判断剩余的字符串是否是限定条件

			stringstream ss(s);//将输入的第一行转换成流,按照空格对输入的字符串截断
			string s1;
			vector<string> in;
			while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
				in.push_back(s1);
			
			t.ziduanName.push_back(in[0]); //字段名
			t.type_value.push_back(in[1]); //字段类型

			string yueshu = "";
			for (int i = 2; i < in.size(); i++)
			{
				yueshu += in[i];//第二个字符串后面的全部为约束条件
				if (i != in.size() - 1) yueshu += " ";//把约束条件中的空格也读取出来
			}

			if (yueshu == "primary key")
				t.condition.push_back(1);
			else if (yueshu == "unique")
				t.condition.push_back(2);
			else if (yueshu == "not null")
				t.condition.push_back(3);
			else if(yueshu == "") t.condition.push_back(0);
			else{
				_str = _str + " " + yueshu  + " 没有该约束条件" + "\n";
				f1++;
			}
			
		}

		if (f1){
			cout << _str << endl;
			return;
		}

		//把t表存入table向量数组
		table.push_back(t);
		//存储整个数据表
		ofstream fout;
		fout.open("..\\table.txt", ios::app);//以追加的方式打开文件
		//把内容输入到文件中
		fout << t.table_name << " " << t.shuxing_count << endl;
		for (int i = 0; i < t.ziduanName.size(); ++i)//size()函数返回容器中当前元素的个数
		{
			fout << t.ziduanName[i];
			fout << " " << t.type_value[i];
			if (t.condition[i] == 1)
				fout << " primary key" << endl;
			else if (t.condition[i] == 2)
				fout << " unique" << endl;
			else if (t.condition[i] == 3)
				fout << " not null" << endl;
			else
				fout << endl;
		}
		fout << endl;
		fout.close();




		//当建立一个表之后,不仅在table文档中会显示,同时会生成一个以表名为名的txt文件,专门储存这一个表中的数据
		char file[30];
		string tt = "..\\"+ t.table_name + ".txt";
		for (int i = 0; i < tt.length(); ++i)
			file[i] = tt[i];
		file[tt.length()] = '\0';
		//打开这个txt文件
		fout.open(file);
		for (int i = 0; i < t.ziduanName.size() - 1; ++i)
			fout << t.ziduanName[i] << " ";
		fout << t.ziduanName[t.ziduanName.size() - 1] << endl;
		fout.close();


		cout << "建表成功!" << endl;
	}

	return;
}

通过对用户输入的命令进行性语法和语义检查,并提命令中的表名和属性名、属性类型、约束条件等信息,通过获取的信息再次检查信息的合法性比如该表名是否已经在该表中存在,如果存在则不允许建此表并输出相应提示信息,对属性类型的正确与否也做相应的而检查。都通过之后就在指定的路径建一个与表名相同的文件并把表的属性写入在该新建的文件中,在将该表的表名,属性个数以及属性的名、类型名和约束条件写入到一个系统维护的总表中,并且还需要向表向量中加入该表的信息。

3.2.4视图的建立与显示

在这里插入图片描述
主要代码

class VIEW
{
public:
    vector<string> codes;//定义视图的代码
    string view_name;//视图名
};
vector<VIEW> view;
定义视图的表示数据结构,并将视图的信息进行加载保存。

//视图的建立
void My_create_view(string op, int &flag, string str)
{
    string s = "create view ";
    int f = 1;
    for(int i = 0; i < s.length(); ++i)
    {
        if(op[i] != s[i])
        {
            f = 0;
            break;
        }
    }
    if(f)//是creat view的语句
    {
		if (str == "false")
		{
			string sss;
			while (getline(cin, sss) && sss != ";");
			cout << "该用户没有创建视图的权限" << endl;
			
			return;
		}
        flag = 3;
        //creat_view(op);
		string name;
		name = "create view ";
		int i = name.length();
		name = "";


		for( ; (op[i]!='\n' || op[i]!=' ') && i < op.length(); ++i)
			name += op[i];

		VIEW v;
		v.view_name = name;

		string ttt,t1;
		ttt="as ";

		while(getline(cin, t1) && t1 != ";")
			v.codes.push_back(t1);
		v.codes.push_back(";");
		
		for (vector<VIEW>::iterator it = view.begin(); it != view.end(); it++){
			if (it->view_name == v.view_name){
				cout << "\n【" << v.view_name << "】 存在!\n" << endl;
				return;
			}
		}
		view.push_back(v);


		ofstream fout;
		fout.open("..\\view.txt", ios::app);//以追加的方式打开文件
		//把内容输入到文件中
		fout << v.view_name << endl;
		fout<<"create view "<<v.view_name<<endl;
		for(int i = 0; i < v.codes.size(); ++i)
			fout << v.codes[i] << endl;
		fout.close();


		string tt = "..\\" + v.view_name + "_view.txt";

		fout.open(tt.c_str());
		for(int i = 0; i < v.codes.size(); ++i)
			fout << v.codes[i] << endl;
		fout.close();

		 cout << "建立视图成功!" << endl;
    }

    return;
}

通过对输入的视图建立命令进行语义语法的分析,如果有误则输出错误信息;若无误按提取的视图名来判断数据库系统是否已存在该视图名,若不存在则在指定的目录下建议同名的一个文件与之对应并并存储相应的信息,并且需要将这些信息加载到系统总的维护表中。

3.2.5索引的建立与显示

在这里插入图片描述
主要代码

class INDEX
{
public:
	vector<string> code;//定义索引的代码
	string index_name;//索引名
};

vector<INDEX> index;
定义索引的表示数据结构,并将索引的信息进行加载保存。
//索引建立
void My_create_index(string op, int &flag, string str)
{
	string s = "create index ";
	int f = 1;
	for (int i = 0; i < s.length(); ++i)
	{
		if (op[i] != s[i])
		{
			f = 0;
			break;
		}
	}
	if (f)
	{
		if (str == "false")
		{
			string sss;
			while (getline(cin, sss) && sss != ";");
			cout << "该用户没有创建索引的权限" << endl;
			return;
		}
		flag = 4;

		string name;
		name = "create index ";
		int i = name.length();
		name = "";
		for (; (op[i] != '\n' || op[i] != ' ') && i < op.length(); ++i)
			name += op[i];
		INDEX dex;
		dex.index_name = name;
		string t1;
		while (getline(cin, t1) && t1 != ";")//getline以回车为断句,一个回车进行一次循环
			dex.code.push_back(t1);
		dex.code.push_back(";");

		for (vector<INDEX>::iterator it = index.begin(); it != index.end(); it++){
			if (it->index_name == dex.index_name){
				cout << "\n【" << dex.index_name << "】 存在!\n" << endl;
				return;
			}
		}

		index.push_back(dex);


		ofstream fout;
		fout.open("..\\index.txt", ios::app);
		fout << dex.index_name << endl;
		fout << "create index " << dex.index_name << endl;
		for (int i = 0; i < dex.code.size(); ++i)
			fout << dex.code[i] << endl;
		fout.close();

		string tt = "..\\" + dex.index_name + "_index.txt";

		fout.open(tt.c_str());
		for (int i = 0; i < dex.code.size(); ++i)
			fout << dex.code[i] << endl;
		fout.close();

		cout << "建立索引成功!" << endl;
	}

	return;
}

根据用户输入的命令进行语义和语法的分析,如果有误则输出具体的错误信息,方便用户做出修改;反之,通过从命令中提取去的索引名,在指定的路劲下建立与之名对应的文件,并将索引的信息写入其中保存,在索引总表中更新此条信息。

3.2.6表数据的插入

在这里插入图片描述
主要代码

//插入语句
void My_insert(string op, int &flag, string str)
{
	//int insert_no=0;
	string s = "insert into ";
	int f = 1;
	int i = 0;
	for (; i < s.length(); ++i)
	{
		if (op[i] != s[i])
		{
			return;
		}
	}

	string _str = "";
	flag = 5;
	if ( str == "false")
	{
		_str = _str + "该用户没有insert的权限\n";
		f = 0;
	}

	//确定往哪个表中插入数据,并判断表是否存在
	string table_name = "";
	while ((i < op.length()) && op[i] == ' ') i++; //跳过空格
	for (; i < op.length() && f; ++i)
	{
		while ((i < op.length()) &&  op[i] != ' ' && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			table_name += op[i++];
		}//if :select sname,sno
		if (op[i] == ' '){
			break;
		}
	}

	//for (; i < op.length() && op[i] != ' '; ++i)
	//	table_name += op[i];

	int k = -1;
	for (int j = 0; j < table.size(); ++j)
	{
		if (table[j].table_name == table_name)
		{
			k = j;//k代表了插入到表的容器中的第几个表中
			break;
		}
	}
	if (k == -1)
	{
		_str = _str + table_name + " 表不存在!\n";
		flag = 0;
		f = 0;
	}

	if ( f && user.root_u == "false"){
		int Ff = 1;
		for (vector<string>::iterator it = user.In_table.begin(); it != user.In_table.end(); it++){
			if ((*it) == table_name){
				Ff = 0;
				break;
			}
		}

		if (Ff){
			cout << "该用户没有表 [" << table_name << "] 的insert权限\n" << endl;

			return;
		}
	}

	//判断语句格式
	s = "values(";
	++i;
	for (int j = 0; j < s.length(); ++j, ++i)
	{
		if (op[i] != s[j])
		{
			_str = _str +  "not find 'values(' !\n";
			flag = 0;
			f = 0;
		}
	}
	//确定插入的数据  values('123','python','某老师',10)
	vector<string> vec;
	string tt = "";
	int _i = 0; //记录属性下标
	int Ichar = 0; //判断是否为字符型
	while ((k != -1) && i < op.length() && op[i] != ')' ) //表存在判断获取
	{
		int _f_ = 0;
		while ( ( i < op.length() ) && op[i] == ' ' || op[i] == ',' || op[i] == ';' || op[i] == ')') i++;
		//char iii = op[i];
		if (op[i] == '\'')
		{
			Ichar = 1;
			if (op[i + 1] == '\'')
			{
				_f_ = 1;
				i ++;
			}
			i++;
		}
		else
		{
			Ichar = 0;
		}


		if(_f_ == 0){
			while ((i < op.length()) && op[i] != '\'' && op[i] != ' ' &&op[i] != ',' && op[i] != ')' ){
				tt += op[i++];
			}
		}
		//int iiii = table[k].type_value.size();
		//int iii = op.length();

		//i < op.length();

		//(_i < table[k].type_value.size());
		//(table[k].type_value[_i] == "int");
		//(table[k].type_value[_i] == "float");
		//(table[k].type_value[_i] == "double");

		if (((i < op.length()) && (_i < table[k].type_value.size())) && ((table[k].type_value[_i] == "int") || (table[k].type_value[_i] == "float") || (table[k].type_value[_i] == "double"))){
			if (Ichar){
				_str = _str +"'"+ tt+"'" + ":not " + table[k].type_value[_i] + "\n";
				f = 0;
			}
		}

		vec.push_back(tt);
		tt = "";

		_i++;
		i++;
		//if (op[i] == ',' || op[i] == ')')//遇到逗号或者右括号就放入容器
		//{
		//	vec.push_back(tt);
		//	tt = "";
		//}
		//else if (op[i] == '\'' || op[i] == ' ')//单引号和空格什么也不做
		//	i;
		//else
		//	tt += op[i];
		//++i;
	}
	
	ofstream fout;
	if (k != -1)
	{
		if (vec.size() != table[k].ziduanName.size())
		{
			cout << "插入的元组与该表不对应!" << endl;
			flag = 0;
			return;
		}

		tt = "..\\" + table[k].table_name + ".txt";


		//判断约束条件
		for (int i = 0; i < table[k].ziduanName.size(); ++i)//轮流判断各个字段
		{
			if (table[k].condition[i] == 1)
			{
				int f_ = 1;
				if (vec[i] == "")
				{
					_str = _str + "主键 (" + table[k].ziduanName[i] + ") 不能为空!\n";
					flag = 0;
					f = 0;
					f_ = 0;
				}
				fstream fin;
				string ttt;
				int found;

				fin.open(tt.c_str());
				while (!fin.eof()){
					while (getline(fin, ttt) && ttt == "");
					found = ttt.find(vec[i]);
					if (found != -1 && f_){
						_str = _str + "主码 (" + table[k].ziduanName[i] + ") : " + vec[i] + " 已存在\n";
						f = 0;
						break;
					}
				}
				fin.close();
			}
			if (table[k].condition[i] == 3)
			if (vec[i] == "")
			{
				_str = _str + table[k].ziduanName[i] + " 约束条件not null,不能为空!\n";
				flag = 0;
				f = 0;
			}
			if (table[k].condition[i] == 2)
			if (vec[i] == "null")
			{
				_str = _str + table[k].ziduanName[i] + " 约束条件unique,不能进行插入!\n";
				flag = 0;
				f = 0;
			}
		}
	}


	if (f){
		fout.open(tt.c_str(), ios::app);
		for (int i = 0; i < vec.size() - 1; ++i)
			fout << vec[i] << " ";
		fout << vec[vec.size() - 1] << endl;
		fout.close();
		cout << "插入成功!" << endl;
		table[k].remcount++;
		cout << "表中共有" << table[k].remcount << "条记录" << endl;
	}
	else
	{
		cout << _str << endl;
	}

	return;
}

对用户输入的命令进行提取,语法和语义的分析,如果有误需要进行错误提示,通过提取的信息进行相应的处理,首先需要检查权限,其次检查表是否存在,然后在对插入的集体数据进行分析,主要检查数据的类型是否符合表中属性的类型和检查该插入数据有没有破坏该表的约束条件,如果有违反这些就需要提示错误信息,并且取消这次操作,如果无误就将该条记录写入对应的表中。

3.2.7表数据的更新

在这里插入图片描述
主要代码

//更新语句
void My_update_0(string op, int& flag, string &up_name, vector<string>& t1, vector<string>& sett, string str, vector<string>& tt, vector<string>& Secolname, vector<int>& AndOrBA, vector<string>& fuhao)
{
	string s = "update ";
	int i = 0;
	int f = 1;
	string _str = "\n";
	string str1 = "";
	for (; i < s.length(); ++i)
	{
		if (s[i] != op[i])
		{
			return;
		}
	}

	flag = 8;
	if (str == "false")
	{
		str1 = str1 + "该用户没有update权限\n";
		f = 0;
	}

	string name = "";
	for (; i < op.length() && f; ++i)
	{
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			name += op[i++];
		}//if :select sname,sno
	}

	up_name = name;//获取表名
	int f1 = 1;
	string _str1 = "";

	if (f){
		int k = -1;
		for (int j = 0; j < table.size(); ++j)
		{
			if (table[j].table_name == name)
			{
				k = j;
				break;
			}
		}

		if (k == -1)
		{
			_str1 = _str1 + name + " 表不存在!\n";
			f = 0;
			f1 = 0;
		}
	}

	if (f1 && f){
		int Ff = 1;
		for (vector<string>::iterator it = user.Up_table.begin(); it != user.Up_table.end(); it++){
			if ((*it) == name){
				Ff = 0;
				break;
			}
		}

		if (Ff){
			str1 = str1 + "该用户没有表 [" + name + "] 的update权限\n";

			f = 0;
		}
	}

	//string sett = "";
	getline(cin, op);
	s = "set ";
	i = 0;
	for (int j = 0; j < s.length(); ++j, ++i)
	{
		if (s[j] != op[i])
		{
			_str = _str + "update: no set\n";
			flag = 0;
			while (op[i++] != ' ');
			f = 0;
			break;
		}
	}

	//set name='。。',获取set 后的属性
	string set;
	while (i < op.length() && f){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格和','
		set = "";
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			set += op[i++]; //提取属性列
		}
		if (set != "")
		{
			sett.push_back(set);
			set = "";
		}
		
		i++; //跳过 =

		if (op[i] == '\'') //属性是字符串
		{
			i++;
		}
		//获取具体的内容,如'001'
		set = "";
		for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
		{
			set += op[i];
		}
		if (set != ""){
			t1.push_back(set);
			set = "";
		}
		
		if (op[i] == '\''){
			i++;
		}
	}

	//for (; i < op.length() && op[i] != '='; ++i)
	//	sett += op[i];
	//if (op[ ++ i] == '\''){
	//	i++;
	//}
	获取属性值
	//for (; i < op.length() && ( op[i] != '\'' || op[i] != ' '); ++i)
	//	t1 += op[i];

	string where = "";
	getline(cin, op);
	s = "where ";
	i = 0;
	for (int j = 0; j < s.length(); ++j, ++i)
	{
		if (s[j] != op[i])
		{
			_str = _str + "update: no where\n";
			while (op[i++] != ' ');
			flag = 0;
			f = 0;
			break;
		}
	}
	//获取条件关键字的属性
	
	while (i < op.length() && f){
		int f_f_ = 0; //between
		int f_f_f = 0; // not between
		string between_str = "";

		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格和','
		where = "";
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			where += op[i++]; //提取属性列
		}
		if (where != "")
		{
			between_str = where;
			Secolname.push_back(where);
			where = "";
		}

		if (op[i] == ' '){
			while (op[i] == ' ') i++; //跳过空格
			while ((i < op.length()) && op[i] != ' '){
				where += op[i++];
			}
			if (where == "not"){
				while (op[i] == ' ') i++; //跳过空格
				while ((i < op.length()) && op[i] != ' '){
					where += op[i++];
				}
			}
			if (where == "between" || where == "BETWEEN")
			{
				fuhao.push_back(">=");
				f_f_f = 1; //between
			}
			else{
				fuhao.push_back("<");
				f_f_f = 0;//not between
			}
			where = "";
			f_f_ = 1;
		}

		if (f_f_ == 0){
			if (i < op.length()){
				where += op[i++];
			}

			if (where != "")
			{
				if (op[i] == '='){
					where += op[i++];
				}
				fuhao.push_back(where);
				where = "";
			}

			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}

			//获取and or
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格和', '
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else if (where == "OR" || where == "or"){
				AndOrBA.push_back(1);
			}
			else if (where != "")
			{
				_str = _str + "no : " + where + "\n";
				f = 0;
			}
		}
		else{
			while (op[i] == ' ') i++;
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}

			//获取and or
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			where = "";
			while (op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (f_f_f && where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else{
				AndOrBA.push_back(1);
			}
			Secolname.push_back(between_str);
			if (f_f_f){
				fuhao.push_back("<=");
			}
			else{
				fuhao.push_back(">");
			}

			while (op[i] == ' ') i++;
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}
			if (op[i] == '\''){
				i++;
			}

			where = "";
			while (i < op.length() && op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else if (where == "OR" || where == "or"){
				AndOrBA.push_back(1);
			}


			f_f_ = 0;
		}
		//while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格和','
		//where = "";
		//while ( (i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
		//	where += op[i++]; //提取属性列
		//}
		//if (where != "")
		//{
		//	Secolname.push_back(where);
		//	where = "";
		//}
		//
		//if (i < op.length()){
		//	where += op[i++];
		//}
		//
		//if (where != "")
		//{
		//	fuhao.push_back(where);
		//	where = "";
		//}

		//if (op[i] == '\'') //属性是字符串
		//{
		//	i++;
		//}
		获取具体的内容,如'001'
		//
		//for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
		//{
		//	where += op[i];
		//}
		//if (where != ""){
		//	tt.push_back(where);
		//	where = "";
		//}
		//
		获取and or
		//if (op[i] == '\'') //属性是字符串
		//{
		//	i++;
		//}
		//while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格和', '
		//for (; i < op.length() && op[i] != ' '; i++){
		//	if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
		//		where += op[i];
		//	}
		//}// for
		 0:and 1:or 2:between and
		//if (where == "and" || where == "AND"){
		//	AndOrBA.push_back(0);
		//}
		//else if (where == "OR" || where == "or"){
		//	AndOrBA.push_back(1);
		//}
		//else if (where != "")
		//{
		//	_str = _str + "no : " + where + "\n";
		//	f = 0;
		//}

		//i++;
	}
	
	if (f){
		//fstream file;
		//int found;
		//string __name = "..\\" + up_name + ".txt";
		//file.open(__name.c_str());
		//string line;
		//while (!file.eof())
		//{
		//	getline(file, line);
		//	found = line.find(t1);

		//	if (found != -1){
		//		cout << "此记录存在\n\n";
		//		return;
		//	}
		//}

		//file.close();
	}
	else
	{
		t1.clear();
		tt.clear();
		cout << _str1 << endl;
		cout << _str << endl;
		cout << str1 << endl;
	}

}

该部分主要是对输入的命令进行提取,用不同的向量将提取出的需要设置的属性名和对应的属性值,更新记录满足的条件(属性名、属性值以及逻辑运算and、or和between and 的逻辑记录下来),还有该命令如果有误需要将错误的信息分析出来并且需要提示错误具体内容(比如:表是否存在,属性名是否正确,该命令的关键字是否正确等信息)

void My_update_1(string &up_name, vector<string>& t1, vector<string>& tt, vector<string>& sett, vector<string>& Secolname, vector<int>& AndOrBA, vector<string>& fuhao)
{
	TABLE t;
	int numcounts = 0;
	
	t.table_name = up_name;
	t.table_name = "..\\" + t.table_name + ".txt";
	fstream file;
	int found;
	{//判断主码是否冲突
		file.open(t.table_name.c_str());//c_str是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址

		string line;
		int getFlag = 1;
		vector<string> Findin;//存表的属性 ---- 第一排
		while (!file.eof())
		{
			if (getFlag){
				getFlag = 0;
				while( getline(file, line) && line =="");//逐条读取txt文件的内容且不为空
				//tt就是关键字,从select_t()函数中获取的
				stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
				string s1;
				while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
					Findin.push_back(s1);

				int f_f1 = 0; //判断显示属性是否正确
				int f_f2 = 0;//判断查询属性是否正确

				for (int i = 0; i < sett.size(); i++){
					if (Find_shuxing(Findin, sett[i]) == -1){//属性错误
						if (f_f1 == 0){
							cout << "\nset : ";
						}
						cout << sett[i] << " ";
						f_f1++;
					}
				}
				for (int i = 0; i < Secolname.size(); i++){
					if (Find_shuxing(Findin, Secolname[i]) == -1){//属性错误
						if (f_f2 == 0){
							cout << "\nwhere : ";
						}
						cout << Secolname[i] << " ";
						f_f2++;
					}
				}
				if (f_f1 || f_f2){
					cout << "\n以上属性不是表 " << up_name << " 的属性\n" << endl;
					file.close();
					return;
				}
			}// if getFlag

			
			{
				while (getline(file, line) && line != "")//逐条读取txt文件的内容---跳过空行
				{
					//tt就是关键字,从select_t()函数中获取的
					stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
					string s1;
					vector<string> in;
					while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
						in.push_back(s1);
					int ci = 0;
					for(int ii = 0; ii < sett.size(); ii ++ ){
						if (Find_shuxing_z(up_name, sett[ii])){
							if (in[Find_shuxing(Findin, sett[ii])] == t1[ii]){
								if (ci == 0)
									cout << "\n主码:";
								cout << t1[ii] << " ";
								ci++;
							}
						}	
					}
					if (ci){
						cout  << " 存在\n" << endl;
						file.close();
						return;
					}
				}
			}

		}//while eof()
		file.close();

	}//判断主码是否冲突
		



	file.open(t.table_name.c_str());//c_str()函数返回当前字符串的首字符地址
	ofstream outfile("in2.txt", ios::out | ios::trunc);

	int ff1 = 0;
	string line;
	int getFlag = 1;
	vector<string> Findin;//存表的属性 ---- 第一排

	{//查找记录满足
		while (!file.eof())
		{
			if (getFlag){
				getFlag = 0;
				while (getline(file, line) && line == "");//逐条读取txt文件的内容且不为空
				outfile << line << endl;
				//tt就是关键字,从select_t()函数中获取的
				stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
				string s1;
				while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
					Findin.push_back(s1);
			}

			while (getline(file, line) && line != "")//逐条读取txt文件的内容---跳过空行
			{
				//tt就是关键字,从select_t()函数中获取的
				stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
				string s1;
				vector<string> in;
				while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
					in.push_back(s1);

				vector<string>::iterator it;
				int ii = 0; //查找属性个数
				int Flag = 0; // 确定条件的是否满足

				int fff1 = 0; //该行记录是否符合
				int And = -1; //and/or 组合条件判断



				for (it = Secolname.begin(); it != Secolname.end(); it++, ii++) //属性查找 ---属性
				{
					if (fuhao[ii] == "=")
					{
						if (in[Find_shuxing(Findin, *it)] == tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}
					else if (fuhao[ii] == ">")
					{
						if ((in[Find_shuxing(Findin, *it)]) > tt[ii]) //通过属性的下标取值
						{
							fff1++;
							Flag = 1;
						}
					}
					else if (fuhao[ii] == "<")
					{
						if ((in[Find_shuxing(Findin, *it)]) < tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}
					else if (fuhao[ii] == "<=")
					{
						if ((in[Find_shuxing(Findin, *it)]) <= tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}
					else if (fuhao[ii] == ">=")
					{
						if ((in[Find_shuxing(Findin, *it)]) >= tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}
					if (AndOrBA.size() == 0)
					{ // no and/or
						if (fff1) //找到
						{
							ff1++;
							/*for (int i = 0; i < Xscolname.size(); i++){
							cout << in[Find_shuxing(Findin, Xscolname[i])] << "\t";
							}*/
							//update values
							numcounts++;
							for (int ii = 0; ii < sett.size(); ii++){
								int pos;
								string t2 = in[Find_shuxing(Findin, sett[ii])];

								pos = line.find(t2);

								line.replace(pos, t2.length(), t1[ii]);//用新的串替换掉指定的串, 用t1替换指定字符串从起始位置pos开始长度为len的字符
								//numcounts++;
								//pos = line.find(t2);//继续查找指定的串,直到所有的都找到为止					
							}
							outfile << line << endl;
							Flag = 0; //清除防止多输出
						}
						else{
							outfile << line << endl;
						}
						
						break; // break for()
					}  // if no and/or
					else
					{ // have and/or  一条记录
						if (ii < AndOrBA.size() && AndOrBA[ii] == 0){ //and 要求后一条件满足
							if (fff1) //前一个条件满足, 在判断后面的条件
							{
								Flag = 0;
								/*	ff1 = 0;*/
								fff1 = 0;
								And = 1;
							}
							else{ //前一个条件不满足, 则此记录不满足
								int fFlag = 1;
								And = 0;
								for (int i = ii; i < AndOrBA.size(); i++){
									if (AndOrBA[i] == 1) //后面有or继续
									{
										fFlag = 0;
										break;
									}
								}
								if (fFlag)
								{
									Flag = 0;
									break; //break for()
								}

							}
						}
						else if (ii < AndOrBA.size() && AndOrBA[ii] == 1){  //or 不处理
							if (And == 0 && fff1){
								Flag = 0;
								fff1 = 0;
							}
							else if (fff1){
								break;
							}
						}
					}// have and/or
				}  //for

				if (Flag)
				{ //have and/or
					/*for (int i = 0; i < Xscolname.size(); i++){
						cout << in[Find_shuxing(Findin, Xscolname[i])] << "\t";
					}*/
					for (int ii = 0; ii < sett.size(); ii++){
						int pos;
						string t2 = in[Find_shuxing(Findin, sett[ii])];

						pos = line.find(t2);

						line.replace(pos, t2.length(), t1[ii]);//用新的串替换掉指定的串, 用t1替换指定字符串从起始位置pos开始长度为len的字符
						//numcounts++;
						//pos = line.find(t2);//继续查找指定的串,直到所有的都找到为止
					}
					outfile << line << endl;
					numcounts++;

					ff1++;
					cout << endl;
				}  // if have and/or
				else if (AndOrBA.size() != 0){
					outfile << line << endl;
				}
			}
		} // whiel eof
	}//查找记录满足


	//if (found == -1)//如果某一行没有找到要查找的关键字,found为默认值-1.
	//{
	//	outfile << line << endl;
	//}
	//else
	//{
	//	int pos;

	//	pos = line.find(t2);

	outfile.close();
	file.close();
	ofstream outfile1;
	outfile1.open(t.table_name.c_str());
	fstream file1("in2.txt");

	while (!file1.eof())
	{
		getline(file1, line);
		outfile1 << line << endl;
	}
	outfile1.close();
	file1.close();
	system("del in2.txt");//删除临时文件
	if (numcounts)
	{
		cout << "更新成功!" << endl;
		cout << "成功修改了" << numcounts << "个元组!" << endl;
	}
	else{
		cout << "\n【记录不存在】\n" << endl;
	}

}

主要根据提取的关键性的数据和条件,对表中的进行匹配,找到满足条件的记录,最主要的是对逻辑部分的条件运算判断,将满足的记录进行更新操作然后写回表中,完成表的数据更新操作。

3.2.8表数据的删除

在这里插入图片描述
主要代码

//判断删除语句格式
void My_delete_0(string op, int& flag, string &ttname, string str, vector<string>& tt, vector<string>& Secolname, vector<int>& AndOrBA, vector<string>& fuhao)
{
	string s = "delete";
	int i = 0;
	int f = 1;
	for (; i < s.length(); ++i)
	{
		if (s[i] != op[i])
			return;
	}

	string _str = "\n";
	string str1 = "";
	
	flag = 6;
	if (str == "false")
	{
		str1 = str1 + "该用户没有delete的权限\n";
		f = 0;
	}


	getline(cin, op);
	s = "from ";
	i = 0;
	for (; i < s.length(); ++i)
	{
		if (s[i] != op[i])
		{
			_str = _str + "delete: no find from!\n";
			flag = 0;
			f = 0;
			while (op[i++] != ' ');
			break;
		}
	}

	string name = "";
	/*for (; i < op.length(); ++i)
		name += op[i];*/
	for (; i < op.length(); ++i)
	{
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			name += op[i++];
		}//if :select sname,sno

	}
	
	
	ttname = name;
	int k = -1;
	for (int j = 0; j < table.size(); ++j)
	{
		if (table[j].table_name == name)
		{
			k = j;
			break;
		}
	}
	string _str1 = "";
	int f1 = 1;
	if (k == -1)
	{
		//getline(cin, op);
		_str1 = _str1 + name + "表不存在!\n";
		f = 0;
		f1 = 0;
	}

	if (user.root_u == "false" && f1 && f){
		if (f){
			int Ff = 1;
			for (vector<string>::iterator it = user.De_table.begin(); it != user.De_table.end(); it++){
				if ((*it) == name){
					Ff = 0;
					break;
				}
			}

			if (Ff){
				str1 = str1 + "该用户没有表 [" + name + "] 的delete权限\n";

				f = 0;
			}
		}
	}

	getline(cin, op);
	s = "where ";
	i = 0;
	for (; i < s.length(); ++i)
	{
		if (s[i] != op[i])
		{
			_str = _str +  "delete: no find where!\n";
			flag = 0;
			f = 0;
			while (op[i++] != ' ');
			break;
		}
	}

	string where = "";
	//获取选择的内容名称,即关键字的属性where sno='001' and ssex='男'
	while (i < op.length() && f){
		int f_f_ = 0; //between
		int f_f_f = 0; // not between
		string between_str = "";

		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		where = "";
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			where += op[i++]; //提取属性列
		}
		if (where != ""){
			between_str = where;
			Secolname.push_back(where);
			where = "";
		}

		if (op[i] == ' '){
			while (op[i] == ' ') i++; //跳过空格
			while ((i < op.length()) && op[i] != ' '){
				where += op[i++];
			}
			if (where == "not"){
				while (op[i] == ' ') i++; //跳过空格
				while ((i < op.length()) && op[i] != ' '){
					where += op[i++];
				}
			}
			if (where == "between" || where == "BETWEEN")
			{
				fuhao.push_back(">=");
				f_f_f = 1; //between
			}
			else{
				fuhao.push_back("<");
				f_f_f = 0;//not between
			}
			where = "";
			f_f_ = 1;
		}

		if (f_f_ == 0){
			if ((i < op.length())){
				where += op[i++];
			}

			if (where != "")
			{
				if (op[i] == '='){
					where += op[i++];
				}
				fuhao.push_back(where);
				where = "";
			}

			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}

			//获取and or
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			where = "";
			while (op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else if (where == "OR" || where == "or"){
				AndOrBA.push_back(1);
			}
			else if (where != "")
			{
				_str = _str + "no : " + where + "\n";
				f = 0;
			}
		}
		else{
			while (op[i] == ' ') i++;
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}

			//获取and or
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			where = "";
			while (op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (f_f_f && where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else{
				AndOrBA.push_back(1);
			}
			Secolname.push_back(between_str);
			if (f_f_f){
				fuhao.push_back("<=");
			}
			else{
				fuhao.push_back(">");
			}

			while (op[i] == ' ') i++;
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}
			if (op[i] == '\''){
				i++;
			}

			where = "";
			while (i < op.length() && op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else if (where == "OR" || where == "or"){
				AndOrBA.push_back(1);
			}


			f_f_ = 0;
		}
	} //while

	//string t = "";
	//for (; i < op.length() && op[i] != '='; ++i)
	//	t += op[i];
	        cout<<"t: "<<t<<endl;
	//i = i + 2;
	//for (; i < op.length() && op[i] != '\''; ++i)
	//	tt += op[i];

	if (f)
	{
		//cout << "删除成功!" << endl;
	}
	else{
		ttname = "";
		cout << _str << endl;
		cout << _str1 << endl;
		cout << str1 << endl;	
	}
}

该部分主要是对输入的命令进行提取,用不同的向量将提取出的需要设置的属性名和对应的属性值,删除记录满足的条件(属性名、属性值以及逻辑运算and、or和between and 的逻辑记录下来),还有该命令如果有误需要将错误的信息分析出来并且需要提示错误具体内容(比如:表是否存在,属性名是否正确,该命令的关键字是否正确等信息)

//执行删除操作
void My_delete_1(string &ttname, vector<string>& tt, vector<string>& Secolname, vector<int>& AndOrBA, vector<string>& fuhao)
{
	TABLE t;
	t.table_name = ttname;
	t.table_name = "..\\" + t.table_name + ".txt";//ttname是文件名,tt是要查找的关键字
	fstream file;
	int found;
	file.open(t.table_name.c_str());//它返回当前字符串的首字符地址
	//    cout<<"打开成功"<<endl;
	ofstream outfile("in2.txt", ios::out | ios::trunc);//ios::trunc如果文件已存在则先删除该文件

	string line;

	int numcounts = 0;
	int ff1 = 0;
	int getFlag = 1;

	vector<string> Findin;//存表的属性 ---- 第一排

	{//查找记录满足
		while (!file.eof())
		{
			if (getFlag){
				getFlag = 0;
				while (getline(file, line) && line == "");//逐条读取txt文件的内容且不为空
				outfile << line << endl;
				//tt就是关键字,从select_t()函数中获取的
				stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
				string s1;
				while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
					Findin.push_back(s1);

				//int f_f1 = 0; //判断显示属性是否正确
				int f_f2 = 0;//判断查询属性是否正确

				//for (int i = 0; i < Xscolname.size(); i++){
				//	if (Find_shuxing(Findin, Xscolname[i]) == -1){//属性错误
				//		if (f_f1 == 0){
				//			cout << "select : ";
				//		}
				//		cout << Xscolname[i] << " ";
				//		f_f1++;
				//	}
				//}
				for (int i = 0; i < Secolname.size(); i++){
					if (Find_shuxing(Findin, Secolname[i]) == -1){//属性错误
						if (f_f2 == 0){
							cout << "\nwhere : ";
						}
						cout << Secolname[i] << " ";
						f_f2++;
					}
				}
				if ( f_f2 ){
					cout << "\n以上属性不是表 " << ttname << " 的属性\n" << endl;
					file.close();
					return;
				}
			}

			while (getline(file, line) && line != "")//逐条读取txt文件的内容---跳过空行
			{
				//tt就是关键字,从select_t()函数中获取的
				stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
				string s1;
				vector<string> in;
				while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
					in.push_back(s1);

				vector<string>::iterator it;
				int ii = 0; //查找属性个数
				int Flag = 0; // 确定条件的是否满足

				int fff1 = 0; //该行记录是否符合
				int And = -1; //and/or 组合条件判断



				for (it = Secolname.begin(); it != Secolname.end(); it++, ii++) //属性查找 ---属性
				{
					if (fuhao[ii] == "=")
					{
						if (in[Find_shuxing(Findin, *it)] == tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}
					else if (fuhao[ii] == ">")
					{
						if ((in[Find_shuxing(Findin, *it)]) > tt[ii]) //通过属性的下标取值
						{
							fff1++;
							Flag = 1;
						}
					}
					else if (fuhao[ii] == "<")
					{
						if ((in[Find_shuxing(Findin, *it)]) < tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}
					else if (fuhao[ii] == "<=")
					{
						if ((in[Find_shuxing(Findin, *it)]) <= tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}

					else if (fuhao[ii] == ">=")
					{
						if ((in[Find_shuxing(Findin, *it)]) >= tt[ii]) //通过属性的下标取值
						{
							Flag = 1;
							fff1++;
						}
					}
					if (AndOrBA.size() == 0)
					{ // no and/or
						if (fff1) //找到
						{
							numcounts++;
							Flag = 0; //清除重复
						//	ff1++;
						//	/*for (int i = 0; i < Xscolname.size(); i++){
						//	cout << in[Find_shuxing(Findin, Xscolname[i])] << "\t";
						//	}*/
						//	//update values
						//	numcounts++;
						//	for (int ii = 0; ii < sett.size(); ii++){
						//		int pos;
						//		string t2 = in[Find_shuxing(Findin, sett[ii])];

						//		pos = line.find(t2);

						//		line.replace(pos, t2.length(), t1[ii]);//用新的串替换掉指定的串, 用t1替换指定字符串从起始位置pos开始长度为len的字符
						//		//numcounts++;
						//		//pos = line.find(t2);//继续查找指定的串,直到所有的都找到为止					
						//	}
						//	outfile << line << endl;
						//	Flag = 0; //清除防止多输出
						//}
						//else{
						//	outfile << line << endl;
						}
						else{
							outfile << line << endl;
						}
						break; // break for()
					}  // if no and/or
					else
					{ // have and/or  一条记录
						if (ii < AndOrBA.size() && AndOrBA[ii] == 0){ //and 要求后一条件满足
							if (fff1) //前一个条件满足, 在判断后面的条件
							{
								Flag = 0;
								/*	ff1 = 0;*/
								fff1 = 0;
								And = 1;
							}
							else{ //前一个条件不满足, 则此记录不满足
								int fFlag = 1;
								And = 0;
								for (int i = ii; i < AndOrBA.size(); i++){
									if (AndOrBA[i] == 1) //后面有or继续
									{
										fFlag = 0;
										break;
									}
								}
								if (fFlag)
								{
									Flag = 0;
									break; //break for()
								}

							}
						}
						else if (ii < AndOrBA.size() && AndOrBA[ii] == 1){  //or 不处理
							if (And == 0 && fff1){
								Flag = 0;
								fff1 = 0;
							}
							else if (fff1){
								break;
							}
						}
					}// have and/or
				}  //for

				if (Flag)
				{ //have and/or
					/*for (int i = 0; i < Xscolname.size(); i++){
					cout << in[Find_shuxing(Findin, Xscolname[i])] << "\t";
					}*/
					//for (int ii = 0; ii < sett.size(); ii++){
					//	int pos;
					//	string t2 = in[Find_shuxing(Findin, sett[ii])];

					//	pos = line.find(t2);

					//	line.replace(pos, t2.length(), t1[ii]);//用新的串替换掉指定的串, 用t1替换指定字符串从起始位置pos开始长度为len的字符
					//	//numcounts++;
					//	//pos = line.find(t2);//继续查找指定的串,直到所有的都找到为止
					//}
					//outfile << line << endl;
					numcounts++;

					ff1++;
					//cout << endl;
				}  // if have and/or
				else if (AndOrBA.size() != 0){
					outfile << line << endl;
				}
			}
		} // whiel eof
	}//查找记录满足


	outfile.close();
	file.close();


	ofstream outfile1;
	outfile1.open(t.table_name.c_str());
	fstream file1("in2.txt");
	while (!file1.eof())
	{
		getline(file1, line);
		outfile1 << line << endl;
	}
	outfile1.close();
	file1.close();
	system("del in2.txt");//删除临时文件

	//TABLE ttt;
	for (int counts = 0; counts < table.size(); counts++)
	{
		if (ttname == table[counts].table_name)
		{
			table[counts].remcount -= numcounts;
		}
	}
	//ttt.remcount -= remdelnum;
	if (numcounts)
	{
		cout << "删除成功" << endl;
		cout << "成功删除了" << numcounts << "个元组" << endl;
	}
	else
	{
		cout << "\n【记录不存在】\n" << endl;
	}
}

该部分主要是通过上一个部分提取的关键属性和个属性的值以及逻辑条件来进行表中的的记录分析找到需要删除的记录并更新表中内容。

3.2.9表数据的select

在这里插入图片描述

主要代码

//查询语句
void My_select_0(string op, int& flag, vector<string>& tt, string &ttname, vector<string>& Secolname, vector<string>& Xscolname, string str, vector<int>& AndOrBA, vector<string>& fuhao)
{
	string s = "select ";
	int i = 0;
	int f = 1;
	for (; i < s.length(); ++i)
	{
		if (s[i] != op[i])
			return;
	}

	string str1 = "";

	flag = 7;
	if (str == "false")
	{
		str1 = str1 + "该用户没有select的权限\n";
		f = 0;
	}
	
	//获取列名
	string column_name = "";
	string _str = "\n";
	
	while (i < op.length() && f ){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
				column_name += op[i ++];
		}//if :select sname,sno

		if (column_name != "")
		{
			Xscolname.push_back(column_name);
			column_name = "";
		}
	}//while获取显示列名
	//Xscolname.push_back(column_name);


	string table_name = "";
	getline(cin, op);
	s = "from ";
	i = 0;
	for (; i < s.length(); ++i)
	{
		if (s[i] != op[i])
		{
			_str = _str + "select: not from\n";
			flag = 0;
			f = 0;
			while (op[i++] != ' ');
			break;
		}
	}


	//获取核实表名
	for (; i < op.length() && f; ++i)
	{
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			table_name += op[i ++];
		}//if :select sname,sno
	}
	
	ttname = table_name;

	int f1 = 1;
	string _str1 = "";
	if (f){
		int k = -1;
		for (int j = 0; j < table.size(); ++j)
		{
			if (table[j].table_name == table_name)
			{
				k = j;
				break;
			}
		}

		if (k == -1)
		{
			_str1 = _str1 + table_name + " 表不存在!";
			f = 0;
			f1 = 0;
		}
	}

	if (user.root_u == "false" && f1 && f){
		int Ff = 1;
		for (vector<string>::iterator it = user.Se_table.begin(); it != user.Se_table.end(); it++){
			if ((*it) == table_name){
				Ff = 0;
				break;
			}
		}

		if (Ff){
			str1 = str1 + "该用户没有表 [" + table_name + "] 的select权限\n";

			f = 0;
		}
	}

	string where = "";
	getline(cin, op);
	s = "where ";
	i = 0;
	for (; i < s.length(); ++i)
	{
		if (s[i] != op[i])
		{
			_str = _str +  "select: no where\n";
			while (op[i++] != ' ');
			flag = 0;
			f = 0;
			break;
		}
	}

	//获取选择的内容名称,即关键字的属性where sno='001' and ssex='男'
	while ( i < op.length() && f ){
		int f_f_ = 0; //between
		int f_f_f = 0; // not between
		string between_str = "";

		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		where = "";
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			where += op[i ++]; //提取属性列
		}
		if (where != ""){
			between_str = where;
			Secolname.push_back(where);
			where = "";
		}

		if (op[i] == ' '){
			while (op[i] == ' ') i++; //跳过空格
			while ((i < op.length()) && op[i] != ' '){
				where += op[i++];
			}
			if (where == "not"){
				while (op[i] == ' ') i++; //跳过空格
				while ((i < op.length()) && op[i] != ' '){
					where += op[i++];
				}
			}
			if (where == "between" || where == "BETWEEN")
			{
				fuhao.push_back(">=");
				f_f_f = 1; //between
			}
			else{
				fuhao.push_back("<");
				f_f_f = 0;//not between
			}
			where = "";
			f_f_ = 1;
		}

		if (f_f_ == 0)
		{

			if ((i < op.length())){
				where += op[i++];
			}

			if (where != "")
			{
				if (op[i] == '='){
					where += op[i++];
				}
				fuhao.push_back(where);
				where = "";
			}


			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}

			//获取and or
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			where = "";
			while (op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else if (where == "OR" || where == "or"){
				AndOrBA.push_back(1);
			}
			else if (where != "")
			{
				_str = _str + "no : " + where + "\n";
				f = 0;
			}
		}
		else{
			while (op[i] == ' ') i++;
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}

			//获取and or
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			where = "";
			while (op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if ( f_f_f && where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else{
				AndOrBA.push_back(1);
			}
			Secolname.push_back(between_str);
			if (f_f_f){
				fuhao.push_back("<=");
			}
			else{
				fuhao.push_back(">");
			}
		
			while (op[i] == ' ') i++;
			if (op[i] == '\'') //属性是字符串
			{
				i++;
			}
			//获取具体的内容,如'001'
			where = "";
			for (; i < op.length() && (op[i] != '\'' && op[i] != ' '); ++i)
			{
				where += op[i];
			}
			if (where != ""){
				tt.push_back(where);
				where = "";
			}
			if (op[i] == '\''){
				i++;
			}

			where = "";
			while ( i < op.length() &&  op[i] == ' ') i++; //跳过空格
			for (; i < op.length() && op[i] != ' '; i++){
				if ((op[i] <= 'z' && op[i] >= 'a') || (op[i] <= 'Z' && op[i] >= 'A')){
					where += op[i];
				}
			}// for
			// 0:and 1:or 2:between and
			if (where == "and" || where == "AND"){
				AndOrBA.push_back(0);
			}
			else if (where == "OR" || where == "or"){
				AndOrBA.push_back(1);
			}
			

			f_f_ = 0;
		}
	} //while

	if (f) //语句解释通过
	{
		cout << "\n" << endl;
		//cout << "查询成功!" << endl;
	}
	else{
		ttname = "";
		cout << _str << endl;
		cout << _str1 << endl;  //是否存在
		cout << str1 << endl;
	}
}

通过自己设计的算法来提取命令中的信息,需要按一定的格式提取命令中的需要查询的条件,并将它们用特定的结构保存,方便运算,还有该命令如果有误需要将错误的信息分析出来并且需要提示错误具体内容(比如:表是否存在,属性名是否正确,该命令的关键字是否正确等信息)

void My_select_1(string &ttname, vector<string>& tt, vector<string>& Secolname, vector<string>& Xscolname, vector<int>& AndOrBA, vector<string>& fuhao)
{
	TABLE t;
	t.table_name = ttname;
	t.table_name = "..\\"+t.table_name+".txt";//ttname是文件名,tt是要查找的关键字
	fstream file;
	int found;
	int ff1 = 0; //是否有满足
	int f_ff = 1; //判断查询结果表头是否打印
	file.open(t.table_name.c_str());//c_str是Borland封装的String类中的一个函数,它返回当前字符串的首字符地址


	string line;
	int getFlag = 1;
	vector<string> Findin;//存表的属性 ---- 第一排
	while (!file.eof())
	{
		if (getFlag){
			getFlag = 0;
			while (getline(file, line) && line == "");//逐条读取txt文件的内容且不为空
			//tt就是关键字,从select_t()函数中获取的
			stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
			string s1;
			while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
				Findin.push_back(s1);

			int f_f1 = 0; //判断显示属性是否正确
			int f_f2 = 0;//判断查询属性是否正确

			for (int i = 0; i < Xscolname.size(); i++){
				if (Find_shuxing(Findin, Xscolname[i]) == -1){//属性错误
					if (f_f1 == 0){
						cout << "select : ";
					}
					cout << Xscolname[i] << " ";
					f_f1++;
				}
			}
			for (int i = 0; i < Secolname.size(); i++){
				if (Find_shuxing(Findin, Secolname[i]) == -1){//属性错误
					if (f_f2 == 0){
						cout << "\nwhere : ";
					}
					cout << Secolname[i] << " ";
					f_f2++;
				}
			}
			if (f_f1 || f_f2){
				cout << "\n以上属性不是表 " << ttname << " 的属性\n" << endl;
				file.close();
				return;
			}
		}

		if (f_ff){
			cout << "--------------------------------------\n";
			for (int i = 0; i < Xscolname.size(); i++){
				cout << Xscolname[i] << "\t";
			}
			cout << endl;
			cout << "--------------------------------------\n";
			f_ff = 0;
		}

		while (getline(file, line) && line != "")//逐条读取txt文件的内容---跳过空行
		{
			//tt就是关键字,从select_t()函数中获取的
			stringstream ss(line);//将输入的第一行转换成流,按照空格对输入的字符串截断
			string s1;
			vector<string> in;
			while (ss >> s1)//抽取ss中的值到s1,每个循环中ss就被按照空格截断
				in.push_back(s1);

			vector<string>::iterator it;
			int ii = 0; //查找属性个数
			int Flag = 0; // 确定条件的是否满足

			int fff1 = 0; //该行记录是否符合
			int And = -1; //and/or 组合条件判断



			for (it = Secolname.begin(); it != Secolname.end(); it++, ii++) //属性查找 ---属性
			{
				if (fuhao[ii] == "=")
				{
					//int iii = Find_shuxing(Findin, *it);
					//string str_1 = in[iii];
					//string str_2 = tt[ii];

					if (in[Find_shuxing(Findin, *it)] == tt[ii]) //通过属性的下标取值
					{
						//if (AndOrBA.size() == 0)
						//{ // no and/or
						//	for (int i = 0; i < Xscolname.size(); i++){
						//		cout << in[Find_shuxing(ttname, Xscolname[i])] << " ";
						//	}
						//}  // if no and/or
						Flag = 1;
						//ff1++;
						fff1++;
					}
				}
				else if (fuhao[ii] == ">")
				{
					if ((in[Find_shuxing(Findin, *it)]) > tt[ii]) //通过属性的下标取值
					{
						//if (AndOrBA.size() == 0)
						//{ // no and/or
						//	for (int i = 0; i < Xscolname.size(); i++){
						//		cout << in[Find_shuxing(ttname, Xscolname[i])] << " ";
						//	}
						//}  // if no and/or
						//ff1++;
						fff1++;
						Flag = 1;
					}
				}
				else if (fuhao[ii] == "<")
				{
					if ((in[Find_shuxing(Findin, *it)]) < tt[ii]) //通过属性的下标取值
					{
						//if (AndOrBA.size() == 0)
						//{ // no and/or
						//	for (int i = 0; i < Xscolname.size(); i++){
						//		cout << in[Find_shuxing(ttname, Xscolname[i])] << " ";
						//	}
						//}  // if no and/or
						Flag = 1;
						//ff1++;
						fff1++;
					}
				}
				else if (fuhao[ii] == "<=")
				{
					if ((in[Find_shuxing(Findin, *it)]) <= tt[ii]) //通过属性的下标取值
					{
						//if (AndOrBA.size() == 0)
						//{ // no and/or
						//	for (int i = 0; i < Xscolname.size(); i++){
						//		cout << in[Find_shuxing(ttname, Xscolname[i])] << " ";
						//	}
						//}  // if no and/or
						Flag = 1;
						//ff1++;
						fff1++;
					}
				}
				else if (fuhao[ii] == ">=")
				{
					if ((in[Find_shuxing(Findin, *it)]) >= tt[ii]) //通过属性的下标取值
					{
						//if (AndOrBA.size() == 0)
						//{ // no and/or
						//	for (int i = 0; i < Xscolname.size(); i++){
						//		cout << in[Find_shuxing(ttname, Xscolname[i])] << " ";
						//	}
						//}  // if no and/or
						Flag = 1;
						//ff1++;
						fff1++;
					}
				}
				if (AndOrBA.size() == 0)
				{ // no and/or
					if (fff1) //找到
					{
						ff1++;
						for (int i = 0; i < Xscolname.size(); i++){
							cout << in[Find_shuxing(Findin, Xscolname[i])] << "\t";
						}
						cout << endl;
						Flag = 0; //清除防止多输出
					}
					break; // break for()
				}  // if no and/or
				else
				{ // have and/or  一条记录
					if (ii < AndOrBA.size() && AndOrBA[ii] == 0){ //and 要求后一条件满足
						if (fff1) //前一个条件满足, 在判断后面的条件
						{
							Flag = 0;
						/*	ff1 = 0;*/
							fff1 = 0;
							And = 1;
						}
						else{ //前一个条件不满足, 则此记录不满足
							int fFlag = 1;
							And = 0;
							for (int i = ii; i < AndOrBA.size(); i++){
								if (AndOrBA[i] == 1) //后面有or继续
								{
									fFlag = 0;
									break;
								}
							}
							if (fFlag)
							{
								Flag = 0;
								break; //break for()
							}
							
						}
					}
					else if (ii < AndOrBA.size() && AndOrBA[ii] == 1){  //or 不处理
						if (And == 0 && fff1){
							Flag = 0;
							fff1 = 0;
						}
						else if (fff1){
							break;
						}
					}
				}// have and/or
			}  //for

			if (Flag)
			{ //have and/or
				for (int i = 0; i < Xscolname.size(); i++){
					cout << in[Find_shuxing(Findin, Xscolname[i])] << "\t";
				}
				ff1++;
				cout << endl;
			}  // if have and/or

			//found = line.find(tt);//found的值为要查找的关键字在所在行的下标
			//if (found != -1)//如果某一行没有找到要查找的关键字,found为默认值-1.
			//{
			//	if (ff1 == 0){
			//		cout << "查询成功!" << endl;
			//	}
			//	cout << line << endl;//将有关键字所在行的内容打印在屏幕上
			//	ff1++;
			//}
		}
	} // whiel eof

	if (ff1 == 0){
		cout << "\n【记录不存在或无满足条件的记录】\n" << endl;
	}
	else
	{
		cout << "\n[一共查询到满足条件的 【" << ff1 << "】 条记录]\n" << endl;
	}
	file.close();
}

通过需要查询的表,读取表的属性信息,通过表的数=属性信息,结合对表中的数据进行提取的逻辑运算找到满条件的记录,并按查询的显示要求显示记录。

3.2.10权限grant和revoke

在这里插入图片描述
主要代码

void My_grant(string op, int &flag, string str)
{

	string compstr = "grant ";
	vector <string> privilege;
	vector <string> tablesname;
	vector <string> user_name;

	string _str = "\n";
	int ff = 0;
	int fff = 1;

	int i = 0;
	//字符串比较
	for (i = 0; i < compstr.length(); i++)
	{
		if (op[i] != compstr[i])
		{
			return;
		}
	}
	if (str != "true")
	{
		_str = _str + "该用户没有grant权限\n";
		ff = 1;
	}
	flag = 9;

	string rempri = "";
	while (i < op.length() && ff == 0){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			rempri += op[i++];
		}//if :select sname,sno

		if (rempri != "")
		{
			privilege.push_back(rempri);
			rempri = "";
		}
	}//while获取附加的权限

	//if (i == compstr.length()) //判断成功,是Grant命令的正确起始字符
	//{
	//	string rempri = "";
	//	for (; i < op.length() && (ff == 0); i++)
	//	{
	//		if (op[i] != ',' && i < op.length() && op[i] != ' ')
	//		{
	//			rempri += op[i];
	//		}
	//		else if (op[i] == ',')
	//		{
	//			privilege.push_back(rempri);
	//			rempri = "";
	//		}
	//	}
	//}
	getline(cin, op);
	compstr = "on table ";

	fff = 1;
	for (i = 0; i < compstr.length(); i++)
	{
		if (compstr[i] != op[i])
		{
			if (fff){
				_str = _str + "grant语句格式错误(on table)\n";
				fff = 0;
			}
			ff = 1;
		}
	}


	while (i < op.length() && ff == 0){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			rempri += op[i++];
		}//if :select sname,sno

		if (rempri != "")
		{
			tablesname.push_back(rempri);
			rempri = "";
		}
	}//while获取附加的权限的表
	//string remstr = "";
	//for (; i < op.length() && (ff == 0); i++)
	//{
	//	int index = 0;
	//	if (op[i] != ',' && i < op.length() && op[i] != ' ' )
	//	{
	//		remstr += op[i];
	//	}
	//	else if (op[i] == ',' || i = op.length() )
	//	{
	//		tablesname.push_back(remstr);
	//		remstr = "";
	//	}

	//}

	getline(cin, op);
	compstr = "to ";

	fff = 1;
	for (i = 0; i < compstr.length(); i++)
	{
		if (compstr[i] != op[i])
		{
			//while (getline(cin, op) && op[op.length() - 1] != ';' );
			if (fff){
				_str = _str + "grant语句格式错误(to)\n";
				fff = 0;
			}
			ff = 1;
		}
	}

	while (i < op.length() && ff == 0 ){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			rempri += op[i++];
		}//if :select sname,sno

		if (rempri != "")
		{
			user_name.push_back(rempri);
			rempri = "";
		}
	}//while获取附加的用户

	//remstr = "";
	//for (; i < op.length() && (ff == 0); i++)
	//{
	//	int index = 0;
	//	if (op[i] != ',' &&  i < op.length() && op[i] != ';' && op[i] != ' ')
	//	{
	//		remstr += op[i];
	//	}
	//	else if (op[i] == ',' || op[i] == ';')
	//	{
	//		user_name.push_back(remstr);
	//		remstr = "";
	//	}

	//}


	for (vector <string> ::iterator it1 = user_name.begin(); it1 != user_name.end() && (ff==0); it1++){
		int f = 1;
		for (vector<USER>::iterator it = User.begin(); it != User.end(); it++)
		{
			if ((*it1) == it->name){ //用户存在
				f = 0;
				for (vector<string>::iterator itr = privilege.begin(); itr != privilege.end(); itr++)
				{
					if (*itr == "create")
					{
						it->r_create = "true";
						cout << "成功授予用户create权限" << endl;
					}
					else if (*itr == "select")
					{
						it->r_select = "true";
						
						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							int f = 1;
							for (vector<string>::iterator itt = it->Se_table.begin(); itt != it->Se_table.end(); itt++)
							{
								if ((*itt) == (*it2))
								{
									f = 0;
								}
							}
							if (f)
							{
								it->Se_table.push_back(*it2);
							}
						}

						cout << "成功授予用户select权限" << endl;
					}
					else if (*itr == "insert")
					{
						it->r_insert = "true";
						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							int f = 1;
							for (vector<string>::iterator itt = it->In_table.begin(); itt != it->In_table.end(); itt++)
							{
								if ((*itt) == (*it2))
								{
									f = 0;
								}
							}
							if (f)
							{
								it->In_table.push_back(*it2);
							}
						}
						cout << "成功授予用户insert权限" << endl;
					}
					else if (*itr == "delete")
					{
						it->r_delete = "true";
						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							int f = 1;
							for (vector<string>::iterator itt = it->De_table.begin(); itt != it->De_table.end(); itt++)
							{
								if ((*itt) == (*it2))
								{
									f = 0;
								}
							}
							if (f)
							{
								it->De_table.push_back(*it2);
							}
						}
						cout << "成功授予用户delete权限" << endl;
					}
					else if (*itr == "update")
					{
						it->r_update = "true";
						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							int f = 1;
							for (vector<string>::iterator itt = it->Up_table.begin(); itt != it->Up_table.end(); itt++)
							{
								if ((*itt) == (*it2))
								{
									f = 0;
								}
							}
							if (f)
							{
								it->Up_table.push_back(*it2);
							}
						}
						cout << "成功授予用户update权限" << endl;
					}
				}
				//user = *it;
			}
		}
		if(f){
			cout << *it1 << " 用户不存在!" << endl;
		}
	}

	if (ff){
		cout << _str << endl;
	}
	else{
		WriteUser();
	}	
	return;
}

首先对命令进行语法和语义分析,并提取主要的信息用户名、表名和权限。然后按要求进行授予权限操作,并把修改后的信息告诉系统和更新相对应的管理文件,还有该命令如果有误需要将错误的信息分析出来并且需要提示错误具体内容(比如:表是否存在,属性名是否正确,该命令的关键字是否正确等信息)

void My_revoke(string op, int &flag, string str)
{
	string compstr = "revoke ";
	vector <string> privilege;
	vector <string> tablesname;
	vector <string> user_name;

	int i = 0;
	//字符串比较
	for (i = 0; i < compstr.length(); i++)
	{
		if (op[i] != compstr[i])
		{
			return;
		}
	}

	string _str = "\n";
	int ff = 0;
	int fff = 1;

	if (str != "true")
	{
		_str = _str + "该用户没有revoke权限\n";
		ff = 1;
	}
	flag = 1;

	string rempri = "";
	while (i < op.length() && ff == 0){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			rempri += op[i++];
		}//if :select sname,sno

		if (rempri != "")
		{
			privilege.push_back(rempri);
			rempri = "";
		}
	}//while获取附加的权限
	//if (i == compstr.length()) //判断成功,Revoke是命令的正确起始字符
	//{
	//	string rempri = "";
	//	for (; i < op.length(); i++)
	//	{
	//		if (op[i] != ',' && op[i] != '\n')
	//		{
	//			rempri += op[i];
	//		}
	//		else if (op[i] == ',')
	//		{
	//			privilege.push_back(rempri);
	//			rempri = "";
	//		}
	//	}
	//}
	getline(cin, op);
	compstr = "on table ";

	fff = 1;
	for (i = 0; i < compstr.length(); i++)
	{
		if (compstr[i] != op[i]){
			if (fff)
			{
				_str = _str + "revoke语句格式错误(on table)\n";
				fff = 0;
			}
			ff = 1;
		}
			
	}

	while (i < op.length() && ff == 0){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			rempri += op[i++];
		}//if :select sname,sno

		if (rempri != "")
		{
			tablesname.push_back(rempri);
			rempri = "";
		}
	}//while获取附加的权限的表

	//string remstr = "";
	//for (; i <= op.length(); i++)
	//{
	//	int index = 0;
	//	if (op[i] != ',' && op[i] != '\n')
	//	{
	//		remstr += op[i];
	//	}
	//	else if (op[i] == ',')
	//	{
	//		tablesname.push_back(remstr);
	//		remstr = "";
	//	}
	//}

	getline(cin, op);
	compstr = "from ";

	fff = 1;
	for (i = 0; i < compstr.length(); i++)
	{
		if (compstr[i] != op[i]){
			if (fff){
				_str = _str + "revoke语句格式错误(from)\n";
				fff = 0;
			}
			ff = 1;
		}
	}

	while (i < op.length() && ff == 0){
		while ((i < op.length()) && op[i] == ' ' || op[i] == ',' || op[i] == ';') i++; //跳过空格
		while ((i < op.length()) && (op[i] <= 'z' && op[i] >= 'a') || (op[i] <= '9' && op[i] >= '0') || (op[i] == '_')){
			rempri += op[i++];
		}//if :select sname,sno

		if (rempri != "")
		{
			user_name.push_back(rempri);
			rempri = "";
		}
	}//while获取附加的用户

	//remstr = "";
	//for (; i < op.length(); i++)
	//{
	//	int index = 0;
	//	if (op[i] != ',' && op[i] != '\n' && op[i] != ';')
	//	{
	//		remstr += op[i];
	//	}
	//	else if (op[i] == ',' || op[i] == ';')
	//	{
	//		user_name.push_back(remstr);
	//		remstr = "";
	//	}

	//}


	for (vector <string> ::iterator it1 = user_name.begin(); it1 != user_name.end(); it1++){
		int f = 1;
		for (vector<USER>::iterator it = User.begin(); it != User.end(); it++)
		{
			if ((*it1) == it->name)
			{ //用户存在
				f = 0;
				for (vector<string>::iterator itr = privilege.begin(); itr != privilege.end(); itr++)
				{
					if (*itr == "create")
					{
						it->r_create = "false";
						cout << "成功收回create权限" << endl;
					}
					else if (*itr == "select")
					{
						if (it->Se_table.size() == 0)
						{
							it->r_select = "false";
						}

						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							vector<string> T;
							for (vector<string>::iterator itt = it->Se_table.begin(); itt != it->Se_table.end(); itt++)
							{
								if ((*itt) != (*it2))
								{
									T.push_back(*itt);
								}
							}
							it->Se_table = T;
						}

						cout << "成功收回select权限" << endl;
					}
					else if (*itr == "insert")
					{
						if (it->In_table.size() == 0)
						{
							it->r_insert = "false";
						}
						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							vector<string> T;
							for (vector<string>::iterator itt = it->In_table.begin(); itt != it->In_table.end(); itt++)
							{
								if ((*itt) != (*it2))
								{
									T.push_back(*itt);
								}
							}
							it->In_table = T;
						}
						cout << "成功收回insert权限" << endl;
					}
					else if (*itr == "delete")
					{
						if (it->De_table.size() == 0)
						{
							it->r_delete = "false";
						}
						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							vector<string> T;
							for (vector<string>::iterator itt = it->De_table.begin(); itt != it->De_table.end(); itt++)
							{
								if ((*itt) != (*it2))
								{
									T.push_back(*itt);
								}
							}

							it->De_table = T;
						}
						cout << "成功收回delete权限" << endl;
					}
					else if (*itr == "update")
					{
						if (it->Up_table.size() == 0)
						{
							it->r_update = "false";
						}
						for (vector<string>::iterator it2 = tablesname.begin(); it2 != tablesname.end(); it2++){
							vector<string> T;
							for (vector<string>::iterator itt = it->Up_table.begin(); itt != it->Up_table.end(); itt++)
							{
								if ((*itt) != (*it2))
								{
									T.push_back(*itt);
								}
							}
							it->Up_table = T;
						}
						cout << "成功收回update权限" << endl;
					}
				}
				//user = *it;
			}
		}
		if(f){
			cout << *it1 << " 用户不存在!" << endl;
		}
	}
	if (ff){
		cout << _str << endl;
	}
	else{
		WriteUser();
	}

/*
	compstr = "";
	for (; i <= op.length(); i++)
	{
		compstr += op[i];
	}
	string judgement = user.name + ";";
	for (int len = 0; len < judgement.length(); len++)
	{
		if (compstr[len] != judgement[len])
			return;
	}
	//int j, k, w;
	USER tempuser = user;
	vector <string> ::iterator itr;
	for (itr = privilege.begin(); itr != privilege.end(); itr++)
	{

		if (*itr == "insert")
		{
			tempuser.r_insert = "false";
			cout << "成功收回用户insert权限" << endl;
		}
		else if (*itr == "delete")
		{
			tempuser.r_delete = "false";
			cout << "成功收回用户delete权限" << endl;
		}
		else if (*itr == "update")
		{
			tempuser.r_update = "false";
			cout << "成功收回用户update权限" << endl;
		}
		else if (*itr == "select")
		{
			tempuser.r_select = "false";
			cout << "成功收回用户select权限" << endl;
		}
		else if (*itr == "create")
		{
			tempuser.r_create = "false";
			cout << "成功收回用户create权限" << endl;
		}

	}
	user = tempuser;
*/
	return;
}

首先对命令进行语法和语义分析,并提取主要的信息用户名、表名和权限。然后按要求进行回收权限操作,并把修改后的信息告诉系统和更新相对应的管理文件,还有该命令如果有误需要将错误的信息分析出来并且需要提示错误具体内容(比如:表是否存在,属性名是否正确,该命令的关键字是否正确等信息)

3.4系统运行过程

·首先登陆系统(超级管理员身份:root 密码:123)
在这里插入图片描述

·可以通过user.txt查看用户名和密码
在这里插入图片描述
·创建表
在这里插入图片描述
·向表中插入数据
在这里插入图片描述
·显示表中的信息
在这里插入图片描述
·删除表中的记录
在这里插入图片描述
·查询表
在这里插入图片描述
在这里插入图片描述

·新建用户
在这里插入图片描述
·更新操作
在这里插入图片描述
·grant/revoke操作

在这里插入图片描述

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Hello Spring

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值