|
|
【程序】點餐系統——資料庫:Access 2003 |
一派掌門 二十級 |
【源文件main.c】 #include <stdio.h> #include <stdlib.h> // system函數所在地 #include <string.h> #include <conio.h> #include "db.h"
int exit_flag = 0; // 程序退出標誌
void show_food() { int type_id; char sql[100]; char type_name[100]; void *stmt1, *stmt2;
int food_id; char food_name[100]; float food_price;
int i; char order_name[100]; char place[100]; stmt1 = db_query("SELECT * FROM Categories"); db_bind_int(stmt1, 1, &type_id); db_bind_str(stmt1, 2, type_name, sizeof(type_name));
system("cls"); // 清屏 while (db_fetch(stmt1)) { printf("------------------類別%d %s-------------------\n", type_id, type_name);
sprintf_s(sql, sizeof(sql), "SELECT FoodID, FoodName, FoodPrice FROM Food WHERE FoodType = %d", type_id); stmt2 = db_query(sql); db_bind_int(stmt2, 1, &food_id); db_bind_str(stmt2, 2, food_name, sizeof(food_name)); db_bind_float(stmt2, 3, &food_price);
for (i = 0; db_fetch(stmt2); i++) { if (i % 3 == 0 && i != 0) putchar('\n'); printf("%d.%s(%.1f元)\t", food_id, food_name, food_price); } putchar('\n');
db_free(stmt2); }
db_free(stmt1);
printf("請輸入所選菜的編號: "); scanf_s("%d", &food_id);
sprintf_s(sql, sizeof(sql), "SELECT * FROM Food WHERE FoodID = %d", food_id); if (!db_has_records(sql)) { puts("該菜不存在!"); _getch(); system("cls"); return; }
fflush(stdin); printf("請輸入客戶名:"); gets_s(order_name, sizeof(order_name)); printf("請輸入用餐地點: "); gets_s(place, sizeof(place)); stmt1 = db_prepare("INSERT INTO Orders (OrderName, FoodID, OrderPlace) VALUES (?, ?, ?)"); db_set_str(stmt1, 1, order_name); db_set_int(stmt1, 2, &food_id); db_set_str(stmt1, 3, place); if (db_exec_stmt(stmt1, 1)) puts("添加訂單成功"); else puts("添加訂單失敗"); _getch(); system("cls"); }
void show_orders() { void *s1; int order_id; char order_name[100]; char food_name[100]; char order_place[100]; char order_time[100];
system("cls"); puts("------------------訂單------------------");
s1 = db_query("SELECT OrderID, OrderName, (SELECT FoodName FROM Food WHERE FoodID = Orders.FoodID), OrderPlace, OrderTime FROM Orders ORDER BY OrderID DESC"); db_bind_int(s1, 1, &order_id); db_bind_str(s1, 2, order_name, sizeof(order_name)); db_bind_str(s1, 3, food_name, sizeof(food_name)); db_bind_str(s1, 4, order_place, sizeof(order_place)); db_bind_str(s1, 5, order_time, sizeof(order_time)); puts("單號\t客戶\t菜名\t地點\t時間"); while (db_fetch(s1)) { printf("%4d %8s %8s %8s %s\n", order_id, order_name, food_name, order_place, order_time); } db_free(s1);
_getch(); system("cls"); }
void handle_order() { int order_id, food_id; char sql[100]; char customer_id[100]; char comment[500]; void *stmt;
printf("請輸入訂單號: "); scanf_s("%d", &order_id);
sprintf_s(sql, sizeof(sql), "SELECT FoodID FROM Orders WHERE OrderID = %d", order_id); stmt = db_query(sql); db_bind_int(stmt, 1, &food_id); if (!db_fetch(stmt)) { db_free(stmt); puts("該訂單不存在!"); _getch(); system("cls"); return; } db_free(stmt);
printf("請輸入客戶身份證號碼: "); fflush(stdin); gets_s(customer_id, sizeof(customer_id));
printf("請輸入客戶評價內容: "); gets_s(comment, sizeof(comment));
stmt = db_prepare("INSERT INTO Comments (FoodID, CustomerID, Comment) VALUES (?, ?, ?)"); db_set_int(stmt, 1, &food_id); db_set_str(stmt, 2, customer_id); db_set_str(stmt, 3, comment); if (db_exec_stmt(stmt, 1)) { sprintf_s(sql, sizeof(sql), "DELETE FROM Orders WHERE OrderID = %d", order_id); db_exec(sql); puts("處理訂單成功"); } else puts("處理訂單失敗"); _getch(); system("cls"); }
void show_comments() { int comment_id, food_id; char food_name[100]; char customer_id[100]; char comment[500]; char time[30]; void *stmt, *stmt2;
system("cls"); stmt = db_query("SELECT * FROM Comments ORDER BY CommentID DESC"); db_bind_int(stmt, 1, &comment_id); db_bind_int(stmt, 2, &food_id); db_bind_str(stmt, 3, customer_id, sizeof(customer_id)); db_bind_str(stmt, 4, comment, sizeof(comment)); db_bind_str(stmt, 5, time, sizeof(time)); while (db_fetch(stmt)) { stmt2 = db_prepare("SELECT FoodName FROM Food WHERE FoodID = ?"); db_set_int(stmt2, 1, &food_id); db_exec_stmt(stmt2, 0); db_bind_str(stmt2, 1, food_name, sizeof(food_name)); db_fetch(stmt2); printf("--------------------評價%d: %d.%s-----------------\n", comment_id, food_id, food_name); printf(" 客戶身份證號: %s\n", customer_id); printf(" 評價內容: %s\n", comment); printf(" 評價時間: %s\n", time); puts("------------------------------------------------"); db_free(stmt2); } db_free(stmt);
_getch(); system("cls"); }
void show_menu() { int n; puts("------------------歡迎使用點餐系統------------------"); puts("--- 1.訂餐 -----"); puts("--- 2.查看訂單 -----"); puts("--- 3.處理訂單 -----"); puts("--- 4.查看評價 -----"); puts("--- 5.退出 -----"); puts("---------------------------------------------------"); printf("請輸入: "); scanf_s("%d", &n); switch (n) { case 1: show_food(); break; case 2: show_orders(); break; case 3: handle_order(); break; case 4: show_comments(); break; case 5: exit_flag = 1; puts("謝謝您的使用...."); break; default: puts("輸入錯誤, 請重新輸入!"); } }
void main() { if (db_connect("data.mdb")) { while (!exit_flag) { show_menu(); } } db_disconnect(); }
|
一派掌門 二十級 |
【頭文件db.h】 /* 資料庫連接與斷開 */ int db_connect(char *dbname); void db_disconnect();
/* Prepared Statement 相關 */ void *db_prepare(char *sql); int db_exec_stmt(void *stmt, int free); // 設置SQL語句中的問號 void db_set_int(void *stmt, int i, int *p); void db_set_str(void *stmt, int i, char *s);
/* 直接執行查詢,不Prepare */ void *db_query(char *sql); // 執行SELECT查詢,需要手動釋放資源 void db_exec(char *sql); // 執行普通查詢 int db_has_records(char *sql); // 直接執行SELECT查詢,判斷結果集是否有記錄 void db_free(void *stmt); // 釋放db_query的資源
/* 記錄集操作 */ int db_fetch(void *stmt); // 獲取一行記錄 // 綁定欄位到變量上 void db_bind_int(void *stmt, int col, int *p); // 以整數類型保存第col列的內容 void db_bind_str(void *stmt, int col, char *buf, int len); // 以字符串類型保存第col列的內容 void db_bind_float(void *stmt, int col, float *p); // 以小數類型保存第col列的內容
| |
一派掌門 二十級 |
【源文件db.c】 /* 這個文件里封裝了很多操作資料庫的函數 參考資料: https://msdn.microsoft.com/en-us/library/ms714562%28v=vs.85%29.aspx*/ #include <stdio.h> #include <conio.h> #include <Windows.h> #include <sqlext.h> #include "db.h" #define DB_DSN "Driver={Microsoft Access Driver (*.mdb)};DBQ=%s;" SQLHENV hEnv; SQLHDBC hConn; SQLRETURN rc; int db_connect(char *dbname) { char szDSN[100]; // 資料庫連接字符串 char szCode[6] = ""; // 錯誤代碼 char szMsg[256] = ""; // 錯誤信息 SQLAllocHandle(SQL_HANDLE_ENV, NULL, &hEnv); SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3_80, (SQLINTEGER)NULL); SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hConn); sprintf_s(szDSN, sizeof(szDSN), DB_DSN, dbname); // 根據資料庫文件名生成資料庫連接字符串 rc = SQLDriverConnectA(hConn, NULL, (SQLCHAR *)szDSN, SQL_NTS, NULL, (SQLSMALLINT)NULL, NULL, (SQLSMALLINT)NULL); // 根據連接字符串連接資料庫 if (!SQL_SUCCEEDED(rc)) { // 連接失敗的錯誤提示 puts("無法連接資料庫!"); rc = SQLGetDiagRecA(SQL_HANDLE_DBC, hConn, 1, (SQLCHAR *)szCode, NULL, (SQLCHAR *)szMsg, sizeof(szMsg) - 1, NULL); if (SUCCEEDED(rc)) { printf("錯誤代碼: %s\n", szCode); printf("錯誤信息: %s\n", szMsg); } else puts("未知錯誤"); _getch(); return 0; // 連接失敗時,函數返回0 } return 1; // 連接成功時,函數返回1 } void db_disconnect() { SQLDisconnect(hConn); SQLFreeHandle(SQL_HANDLE_DBC, hConn); SQLFreeHandle(SQL_HANDLE_ENV, hEnv); } void *db_prepare(char *sql) { SQLHSTMT hStmt; SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt); SQLPrepareA(hStmt, (SQLCHAR *)sql, strlen(sql)); return hStmt; } int db_exec_stmt(void *stmt, int free) { int f = SQL_SUCCEEDED(SQLExecute(stmt)); if (free) db_free(stmt); return f; } void db_set_int(void *stmt, int i, int *p) { static SQLLEN size = sizeof(int); // 該變量的地址必須固定, 所以要加static SQLBindParameter(stmt, i, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, (SQLUINTEGER)NULL, (SQLSMALLINT)NULL, p, (SQLINTEGER)NULL, &size); // 整型變量的地址也必須固定 } void db_set_str(void *stmt, int i, char *s) { static SQLLEN len = SQL_NTS; SQLBindParameter(stmt, i, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, strlen(s), (SQLSMALLINT)NULL, s, (SQLINTEGER)NULL, &len); } void *db_query(char *sql) { void *stmt = db_prepare(sql); SQLExecute(stmt); return stmt; } void db_exec(char *sql) { void *stmt = db_query(sql); db_free(stmt); } int db_has_records(char *sql) { void *stmt = db_query(sql); int r = db_fetch(stmt); db_free(stmt); return r; } void db_free(void *stmt) { SQLFreeHandle(SQL_HANDLE_STMT, stmt); } int db_fetch(void *stmt) { return SQL_SUCCEEDED(SQLFetch(stmt)); } void db_bind_int(void *stmt, int col, int *p) { SQLBindCol(stmt, col, SQL_C_LONG, p, sizeof(int), NULL); } void db_bind_str(void *stmt, int col, char *buf, int len) { SQLBindCol(stmt, col, SQL_C_CHAR, buf, len, NULL); } void db_bind_float(void *stmt, int col, float *p) { SQLBindCol(stmt, col, SQL_C_FLOAT, p, sizeof(float), NULL); }
| |
一派掌門 二十級 |
【資料庫】 
| |
一派掌門 二十級 |
| |
一派掌門 二十級 |
| |
一派掌門 二十級 |
| |
一派掌門 二十級 |
| |
|
|
|