數據庫原理課程的實驗要用嵌入式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;\n", tscore, ttotabs, tconabs); 49 if (tscore == -1) printf("該員工缺勤超過5次,考勤成績永遠置零\n"); 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("\n下面開始考勤,該員工出勤請輸入Y,缺勤請輸入N;\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("\n以下員工默認出勤:\n"); 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("\n"); 86 if (ch[0] == 'Y') rollcall(id, 1); else rollcall(id, 0); 87 } 88 89 void update() { //修改職工信息 90 printf("請輸入要修改員工信息\n"); 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("更新成功\n"); else printf("更新失敗\n"); 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("----------------------------------------------------------------------------------------------\n"); 117 tot++; //考勤次數 118 printf("連接成功,請開始第%d次考勤\n",tot); 119 for (;;) { 120 printf("\n輸入數字代表將要隨機考勤的人數,輸入職工號考察特定員工,需要修改員工信息請輸入U;\n"); 121 printf("輸入Q代表結束本次考勤;\n"); 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("數據庫不存在!\n"); 131 mysql_close(&mysql); 132 return 0; 133 }
