数据库原理课程的实验要用嵌入式SQL实现一个职工考勤功能的程序,在网上学习许久发现C++操作mysql数据库的资料身份少。好不容易在VS2017用C++连接Mysql数据库后,却又发现《数据库系统概论》书里讲的方法(EXEC,通信区什么的)好像用不了qwq(当然可能是我没找到使用的办法)。
于是只能上网找资料模仿着实现:
连接数据库的方法:https://blog.csdn.net/jintingbo/article/details/90631985
https://blog.csdn.net/u013232740/article/details/47777683
Mysql对C++的API:https://blog.csdn.net/u011546283/article/details/50410480
按照上面一步步走应该是可以连上Mysql数据库的;
这里讲一下一些可能的坑点:如果是像Wamp这样的集成环境,Mysql可能会没有include和lib文件夹,不过没关系,到官方网站下载一个免安装版本的ZIP格式,然后把免安装版本的lin和include放到工程目录下就可以了。
连接成功后看上面的API就可以对数据库操作了。其实主要用到也就是:用字符串拼接成SQL语句然后用mysql_query()执行语句,接着用mysql_store_result得到查询结果(如果有的话),最后再用mysql_fetch_row把结果一行一行取出来。
这里贴下我的代码(才疏学浅写得很丑功能简陋,大佬轻喷):
实现的功能是:
随机读取数据库中的记录来生成一份可以任意指定规模到名单,来实现随机考勤。数据库中存放的是职工信息,包括职工号、职工姓名、职工所在部门、部门领导、每一次考勤记录、考勤成绩等。采用嵌入式的SQL编程实现。
基本规则:1)每一次考勤,不在名单中的职工默认考勤通过,2)考勤通过者,相应的考勤成绩+1,且在相应的考勤记录中记录“通过”,3)连续三次考勤不通过,考勤成绩置0,4)累计5次考勤不通过,考勤成绩永久置0。
数据库的设计是:
数据库Rollcall有两个表Staff表和Record表:
Staff表用于存储职工的职工号、职工姓名、职工所在部门、部门领导、总考勤成绩、总缺勤次数、连续缺勤次数。
Record表用于记录每个职工每一次的出勤情况,1代表出勤,0代表缺勤。
按道理来说,这里得考勤记录应该一列一列插入,博主这里没有时间实现了,大家可以尝试这样做。
1 #include <iostream> 2 #include<string> 3 #include<random> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <WinSock.h> 7 #include "mysql.h" //包含MySQL的API函数的头文件 8 #pragma comment(lib,"libmysql.lib") //导入libmysql.lib库 9 using namespace std; 10 MYSQL mysql; 11 int tot = 0; //考勤次数 12 13 void setrec(string id, int abs) { //在record表设置第tot次考勤记录 14 string sql = "update record set RC"+to_string(tot)+"="+to_string(abs)+" where ID=" + id + ";"; 15 mysql_query(&mysql, sql.c_str()); 16 } 17 18 void absence(string id,int &tscore,int &ttotabs,int &tconabs) { //员工id出勤 19 setrec(id, 0); 20 if (tscore < 0) return; 21 ttotabs++; tconabs++; //缺勤,总缺勤次数和连续缺勤次数+1 22 if (tconabs >= 3) tscore = 0; //连续三次考勤不通过,考勤成绩置0 23 if (ttotabs >= 5) tscore = -1; //累计5次考勤不通过,考勤成绩永久置0 24 string sql = "update staff set Score="+to_string(tscore)+",TotAbs="+to_string(ttotabs)+",ConAbs="+to_string(tconabs)+" where ID=" + id + ";"; 25 mysql_query(&mysql, sql.c_str()); //更新数据 26 } 27 void noabsence(string id, int &tscore, int &ttotabs, int &tconabs) { //员工id缺勤 28 setrec(id, 1); 29 if (tscore < 0) return; 30 tscore++; //考勤通过者,相应的考勤成绩+1 31 tconabs = 0; //出勤,连续缺勤次数置零 32 string sql = "update staff set Score=" + to_string(tscore) + ",TotAbs=" + to_string(ttotabs) + ",ConAbs=" + to_string(tconabs) + " where ID=" + id + ";"; 33 mysql_query(&mysql, sql.c_str()); //更新数据 34 } 35 36 void rollcall(string id,int abs) { //考勤函数 37 //cout << id << " " << abs << endl; return; 38 string sql = "select Score,TotAbs,ConAbs from staff where ID="+id+";"; 39 mysql_query(&mysql, sql.c_str()); 40 MYSQL_RES *res = mysql_store_result(&mysql); //读取结果 41 MYSQL_ROW row; //数据库一行查询结果 42 while ((row = mysql_fetch_row(res)) != NULL) { 43 int tscore = atoi(row[0]); //总考勤成绩 44 int ttotabs = atoi(row[1]); //总缺勤次数 45 int tconabs = atoi(row[2]); //连续缺勤次数 46 if (abs == 0) absence(id, tscore, ttotabs, tconabs); 47 else noabsence(id, tscore, ttotabs, tconabs); 48 printf("考勤成绩:%d;总缺勤次数:%d;连续缺勤次数:%d; ", tscore, ttotabs, tconabs); 49 if (tscore == -1) printf("该员工缺勤超过5次,考勤成绩永远置零 "); 50 } 51 } 52 53 string getname(string id) { 54 string sql = "select Name from staff where ID=" + id + ";"; 55 mysql_query(&mysql, sql.c_str()); 56 MYSQL_RES *res = mysql_store_result(&mysql); //读取结果 57 MYSQL_ROW row= mysql_fetch_row(res); 58 return row[0]; 59 } 60 61 void dorandom(int num) { //随机读取数据库num个员工进行考勤 62 string sql = "select ID,Name from Staff;"; 63 mysql_query(&mysql, sql.c_str()); 64 MYSQL_RES *res = mysql_store_result(&mysql); //读取结果 65 MYSQL_ROW row; //数据库一行查询结果 66 string tID[100]; int p = 0; 67 while ((row = mysql_fetch_row(res)) != NULL) { tID[p++] = row[0]; } 68 num = min(num, p); 69 random_shuffle(tID, tID+p); //打乱ID数组制造随机,取前num个作为本次考勤名单 70 printf(" 下面开始考勤,该员工出勤请输入Y,缺勤请输入N; "); 71 for (int i = 0; i < num; i++) { 72 cout<<tID[i]<<" "<<getname(tID[i])<<" Y/N? "; 73 char ch[3]; scanf_s("%s", ch,3); 74 if (ch[0] == 'Y') rollcall(tID[i], 1); else rollcall(tID[i], 0); 75 } 76 printf(" 以下员工默认出勤: "); 77 for (int i = num; i < p; i++) { 78 cout << tID[i] << " " << getname(tID[i]) <<endl; 79 rollcall(tID[i], 1); 80 } 81 } 82 83 void inspect(string id) { // 特别考察职工号ID的员工出勤情况 84 cout << "员工" << id << " " << getname(id) << "是否出勤?出勤请输入Y,缺勤请输入N;"; 85 char ch[3]; scanf_s("%s", ch, 3); printf(" "); 86 if (ch[0] == 'Y') rollcall(id, 1); else rollcall(id, 0); 87 } 88 89 void update() { //修改职工信息 90 printf("请输入要修改员工信息 "); 91 string hid,hname,hdep,hlead; 92 cout << "职工号:"; cin >> hid; 93 cout << "姓名:"; cin >> hname; 94 cout << "部门:"; cin >> hdep; 95 cout << "领导:"; cin >> hlead; 96 string sql = "update staff set Name='" + hname + "',Dep='" + hdep + "',Leader='" + hlead + "' where ID=" + hid+";"; 97 if (!mysql_query(&mysql, sql.c_str())) printf("更新成功 "); else printf("更新失败 "); 98 } 99 100 void Init() { //方便实验:初始化表格数据 101 string sql = "update staff set Score=0,TotAbs=0,ConAbs=0;"; 102 mysql_query(&mysql, sql.c_str()); 103 sql = "update record set RC1=0,RC2=0,RC3=0,RC4=0,RC5=0,RC6=0;RC7=0;RC8=0;RC9=0;"; 104 mysql_query(&mysql, sql.c_str()); 105 } 106 107 int main() 108 { 109 mysql_init(&mysql); 110 //mysql_real_connect连接到MySQL数据库服务器,其中localhost为服务器机器名,root为连接用户名,为密码, 111 //Rollcall为数据库名,3306为端口号 112 if (mysql_real_connect(&mysql, "localhost", "root", "", "Rollcall", 3306, 0, 0) ) { 113 mysql_query(&mysql, "set names gb2312"); //设置字符集防止输出中文乱码 114 Init(); //方便实验:初始化表格数据 115 do { 116 printf("---------------------------------------------------------------------------------------------- "); 117 tot++; //考勤次数 118 printf("连接成功,请开始第%d次考勤 ",tot); 119 for (;;) { 120 printf(" 输入数字代表将要随机考勤的人数,输入职工号考察特定员工,需要修改员工信息请输入U; "); 121 printf("输入Q代表结束本次考勤; "); 122 char s[20]; scanf("%s", s); 123 if (s[0] == 'Q') break; 124 if (s[0]=='U') update(); 125 else if (strlen(s) > 2) inspect(s); 126 else dorandom(atoi(s)); 127 } 128 } while (1); 129 } 130 else printf("数据库不存在! "); 131 mysql_close(&mysql); 132 return 0; 133 }