/*
这个文件里封装了很多操作数据库的函数
参考资料:
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);
}