数据库作业需要使用ODBC接口,但是网上的各种说法不一,并且有些方法尝试后没有用,于是将自己的配置过程发出来~
1、ODBC:
ODBC(Open Database Coonnectivity,开放数据库互连)标准定义了一个API,应用程序用它来打开一个数据库连接、发送查询和更新,以及获取返回结果等。应用程序(例如图形界面、统计程序包或者电子表格)可以使用相同的ODBC API来访问任何一个支持ODBC标准的数据库。
每一个支持ODBC的数据库系统都提供一个和客户端程序相连接的库,但客户端发出一个ODBC API请求,库中的代码就可以和服务器通信来执行被请求动作并取回结果。
2、创建ODBC数据源
在控制面板->管理工具中找到ODBC数据源管理程序
添加新数据源。(添加在用户DSN中)
注意Data Source Name和Database都一定得是英文的,之前因为这两个是中文的,改了很久,不是连接不上数据库,就是连接上了在VS中无法执行SQL命令,将这两个都换成英文后终于连接成功。
添加后进行测试,显示 则表示连接成功。
3、配置VS环境
①新建一个工程OBDC;
②将C:/Program Files\MySQL\MySQL Server 5.7\lib下的libmysql.dll复制到工程的debug文件夹里面;
③设置引用文件的环境变量,在项目->属性->VC++目录下,”include”目录中把C:\Program File\MySQL\MySQL Server 5.7\include加进来,”lib”目录中把C:\Program File\MySQL\MySQL Server 5.7\lib加进来。
④利用SQLExecDirect语句,实现数据库应用程序对数据库的建立、查询、修改、删除等操作,检索查询结果集。
查阅官网资料知道,在ODBC3.x中取代了ODBC2.x中的SQLAllocConnect, SQLAllocEnv, and SQLAllocStmt,改为用SQLAllocHandle 分配环境句柄、连接句柄、语句句柄或者描述符句柄。
到此就配置好啦!
附上自己ODBC代码:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include "sql.h"
#include "sqltypes.h"
#include "sqlext.h"
#include"sqlucode.h"
#include"odbcinst.h"
#include<iostream>
#include<string>
using namespace std;
RETCODE retcode;//结果返回集
SQLHDBC hdbc;//定义链接句柄
void SQL(string);//执行 SQL 语句子程序
int main()
{
string str;
SQLHANDLE henv; //定义环境句柄
unsigned char db[] = "mysql";//ODBC 数据源名称
unsigned char user[] = "root";//用户名
unsigned char password[] = "password";//密码
retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);//声明环境
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); //分配连接句柄
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
retcode = SQLConnect(hdbc, db, SQL_NTS, user, SQL_NTS, password, SQL_NTS);//链接到数据库
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) //成功连接到数据库
{
cout << "成功连接数据库!"<<endl;
while (1)
{
cout << "please input the quary:" << endl;
getline(cin, str);
if (str == "exit") return 0;
SQL(str);
}
}
SQLFreeConnect(hdbc); ////释放链接句柄
SQLFreeEnv(henv); // 释放 ODBC 环境句柄
system("pause");
return 0;
}
void SQL(string str)
{
char L1[50] = { '\0' }; char L2[50] = { '\0' }; char L3[50] = { '\0' }; char L4[50] = { '\0' }; char L5[50] = { '\0' }; char L6[50] = { '\0' };
SQLLEN lenOut1, lenOut2, lenOut3, lenOut4, lenOut5, lenOut6;
SQLHSTMT hstmt;//定义语句句柄
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); //分配语义句柄
if (retcode == SQL_SUCCESS)
{
retcode = SQLExecDirect(hstmt, (SQLCHAR *)(str.c_str()), SQL_NTS); // 把SQL语句送到数据库服务器,请求执行由SQL语句定义的数据库访问
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
cout << "语句执行成功!" << endl;
//将结果集中的属性列一一绑定至变量
retcode = SQLBindCol(hstmt, 1, SQL_C_CHAR, L1, sizeof(L1), &lenOut1);
retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, L2, sizeof(L2), &lenOut2);
retcode = SQLBindCol(hstmt, 3, SQL_C_CHAR, L3, sizeof(L3), &lenOut3);
retcode = SQLBindCol(hstmt, 4, SQL_C_CHAR, L4, sizeof(L4), &lenOut4);
retcode = SQLBindCol(hstmt, 5, SQL_C_CHAR, L5, sizeof(L5), &lenOut5);
retcode = SQLBindCol(hstmt, 6, SQL_C_CHAR, L6, sizeof(L6), &lenOut6); //把所有捆绑过的数据字段的数据拷贝到相应的缓冲区
retcode = SQLFetch(hstmt); //将游标移动到到查询结果集的第一行
while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
if (L2[0] == '\0')
cout << (string)L1 << endl;
else if (L3[0] == '\0')
cout << (string)L1 << "\t" << (string)L2 << endl;
else if (L4[0] == '\0')
cout << (string)L1 << " " << (string)L2 << " " << (string)L3 << endl;
else if (L5[0] == '\0')
cout << (string)L1 << " " << (string)L2 << " " << (string)L3 << " " << (string)L4 << endl;
else if (L6[0] == '\0')
cout << (string)L1 << " " << (string)L2 << " " << (string)L4 << " " << (string)L4 << " " << (string)L5 << endl;
else
cout << (string)L1 << " " << (string)L2 << " " << (string)L4 << " " << (string)L4 << " " << (string)L5 << " " << (string)L6 << endl;
retcode = SQLFetch(hstmt); //将游标移动到到查询结果集的下一行
}
}
}
SQLFreeStmt(hstmt, SQL_DROP); //释放语句句柄
}