作者共發了8篇帖子。 內容轉換:不轉換▼
 
點擊 回復
779 7
【程序】点餐系统——数据库:Access 2003
一派護法 十九級
1樓 發表于:2016-5-10 16:53
【源文件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();
}
一派護法 十九級
2樓 發表于:2016-5-10 16:54
【头文件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列的内容
一派護法 十九級
3樓 發表于:2016-5-10 16:54
【源文件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);
}
一派護法 十九級
4樓 發表于:2016-5-10 16:56
【数据库】


一派護法 十九級
5樓 發表于:2016-5-10 16:56
一派護法 十九級
6樓 發表于:2016-5-10 16:56
一派護法 十九級
7樓 發表于:2016-5-10 16:56
一派護法 十九級
8樓 發表于:2016-5-10 17:40
32位ODBC Access 2010驱动(accdb)下载地址:
https://www.microsoft.com/en-us/download/confirmation.aspx?id=13255

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:779 回複數:7
評論數: ?
作者:巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2016-5-10 17:40
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用共享創意姓名標示-相同方式分享 3.0 Unported許可協議進行許可。