作者共發了2篇帖子。
【草稿】mdb.c
1樓 巨大八爪鱼 2016-5-9 22:05
/*
这个文件里封装了很多操作数据库的函数
参考资料:https://msdn.microsoft.com/en-us/library/ms714562%28v=vs.85%29.aspx
*/

#include <stdio.h>
#include <Windows.h>
#include <sqlext.h>
#include "db.h"

SQLHENV hEnv;
SQLHDBC hConn;
SQLRETURN rc;

// 连接到数据库
int db_connect()
{
    char szCode[6] = "";
    char szTemp[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);
    
    rc = SQLDriverConnectA(hConn, NULL, (SQLCHAR *)DB_DSN, SQL_NTS, NULL, (SQLSMALLINT)NULL, NULL, (SQLSMALLINT)NULL);
    if (!SQL_SUCCEEDED(rc))
    {
        // 连接失败的错误提示
        puts("无法连接数据库!");
        rc = SQLGetDiagRecA(SQL_HANDLE_DBC, hConn, 1, (SQLCHAR *)szCode, NULL, (SQLCHAR *)szTemp, sizeof(szTemp) - 1, NULL);
        if (SUCCEEDED(rc))
        {
            printf("错误代码: %s\n", szCode);
            printf("错误信息: %s\n", szTemp);
        }
        else
            puts("未知错误");

        return 0; // 连接失败时,函数返回0
    }
    return 1; // 连接成功时,函数返回1
}

// 关闭数据库连接并释放资源
void db_disconnect()
{
    SQLDisconnect(hConn);
    SQLFreeHandle(SQL_HANDLE_DBC, hConn);
    SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
}

// 执行SQL查询
void *db_prepare(char *sql)
{
    SQLHSTMT hStmt;
    SQLAllocHandle(SQL_HANDLE_STMT, hConn, &hStmt);
    SQLPrepareA(hStmt, (SQLCHAR *)sql, strlen(sql));
    return hStmt;
}

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_exec_stmt(void *stmt)
{
    int f = SQL_SUCCEEDED(SQLExecute(stmt));
    db_free(stmt);
    return f;
}

// 释放资源
void db_free(void *stmt)
{
    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
}

// 获取一行
int db_fetch(void *stmt)
{
    return SQL_SUCCEEDED(SQLFetch(stmt));
}

// 以整数类型保存第col列的内容
void db_bind_int(void *stmt, int col, int *p)
{
    SQLBindCol(stmt, col, SQL_C_LONG, p, sizeof(int), NULL);
}

// 以字符串类型保存第col列的内容
void db_bind_str(void *stmt, int col, char *buf, int len)
{
    SQLBindCol(stmt, col, SQL_C_CHAR, buf, len, NULL);
}

// 以小数类型保存第col列的内容
void db_bind_float(void *stmt, int col, float *p)
{
    SQLBindCol(stmt, col, SQL_C_FLOAT, p, sizeof(float), NULL);
}

int db_has_records(char *sql)
{
    void *stmt = db_query(sql);
    int r = db_fetch(stmt);
    db_free(stmt);
    return r;
}

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);
}
2樓 巨大八爪鱼 2016-5-9 22:07
#define DB_DSN "Driver={Microsoft Access Driver (*.mdb)};DBQ=data.mdb;"

int db_connect();
void db_disconnect();
void *db_prepare(char *sql);
void *db_query(char *sql);
void db_exec(char *sql);
int db_exec_stmt(void *stmt);
void db_free(void *stmt);

void db_bind_int(void *stmt, int col, int *p);
void db_bind_str(void *stmt, int col, char *buf, int len);
void db_bind_float(void *stmt, int col, float *p);
int db_fetch(void *stmt);

int db_has_records(char *sql);

void db_set_int(void *stmt, int i, int *p);
void db_set_str(void *stmt, int i, char *s);

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2024 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。