C++通过ODBC方式连接数据库SQLServer及增删查改操作【图书借阅系统为例】
文章目录
前言
一、ODBC如何配置
二、SQL Server如何设置账号密码
三、C++连接数据库以及增删查改操作的代码实现
四、源代码
前言
大二学习了《数据库原理及应用》,期末做课程设计。因为大一学的C++,所以决定用C++写。这里以《图书借阅系统》为例,该系统做的并不是很完整,但已经能够体现C++如何对数据库SQL Server进行增删查改操作。以下是本人的学习心得,仅供学习参考。
一、ODBC如何配置
ODBC如何配置
二、SQL Server如何设置账号密码
SQL Server如何设置账号密码
三、C++连接数据库以及增删查改操作的代码实现
1.编程环境:Visual Studio 2019
2.基本原理
想必大家都做过C++的课程设计吧,C++课程设计的数据一般都是以文件的方式存储的。而数据库的课程设计则是以数据库的方式来存储数据的。用C++代码实现对数据库的操作,其实就是在C++环境(visual studio)中输入一段SQL代码(用字符串方式存放),然后调用特定的函数来执行该SQL代码,最后再将结果返回到visual studio中,具体步骤如下:
1、第一步:申请句柄。
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
2、第二步:定义、拼接想要执行的SQL语句(以插入操作代码为例)。如果有需要手动输入的地方,则单独定义出来,最后再拼接成一句完整的SQL语句,最后才能执行。比如我想插入一本图书,但是图书的编号、名称、数量都需要我自己手动输入,那么就需要单独定义、cin图书的编号、名称、数量字符串。最后拼接成完整的一句SQL语句:insert into Books values (‘001’,‘计算机网络’,10)。
string str1 = "use JYXT";//第一句要执行的SQL语句
string str2 = "insert into Books values ('";//第二句要执行的SQL语句
cout << "请依次输入图书编号、图书名称、图书数量" << endl;
string Bno, Bname, Bsum;
cin >> Bno >> Bname >> Bsum;
string str3=str2 + Bno + "','" + Bname + "'," + Bsum + ")";
3、第三步:调用函数执行SQL语句(以插入操作代码为例)。如果ret返回0或1则说明该语句执行成功,否则执行失败。失败原因可能是,你的SQL语句错误(记得先执行use[数据库]这句哦)。这里建议你先在SQL Server执行好,再到visual studio中拼接,注意是英文符号!!!
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);//执行str1这句SQL语句use JYXT
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);//执行str3这句SQL语句insert into Books values ('Bno','Bname',Bsum)
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
cout << "书籍上架成功!" << endl;
}
else {
cout << "书籍上架失败!" << endl;
}
4.第四步:将SQL语句执行后的结果返回(以查询操作代码为例)。比如你想查询一本图书的基本信息,在调用完SQL语句后,你就需要将数据存放下来,然后再打印在黑框中,具体细节都在代码注释里啦(注意规律队形哦)。
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
SQLCHAR str1[10], str2[12], str3[10];//用来存放从数据库获取的列信息,你有几列就定义几个变量
SQLINTEGER len_str1, len_str2, len_str3;//字符串对应长度,你有几列就定义几个变量
//printf("%s\t%s\t%s\n", "书籍编号", "书籍名称", "数量");
cout << "编号" << " " << "书籍名称" << " " << "书籍数量" << endl;
while (SQLFetch(hstmt) != SQL_NO_DATA)
{
//你有几列就调用几次SQLGetData函数,注意找规律哦
SQLGetData(hstmt, 1, SQL_C_CHAR, str1, 10, &len_str1); //获取第一列数据
SQLGetData(hstmt, 2, SQL_C_CHAR, str2, 12, &len_str2); //获取第二列数据
SQLGetData(hstmt, 3, SQL_C_CHAR, str3, 10, &len_str3); //获取第三列数据
printf("%s\t%s\t%s\n", str1,str2, str3);
}
}
3.头文件及全局变量的定义
#undef UNICODE
#undef _UNICODE
#include<Windows.h>
#include <sql.h>
#include <sqlext.h>
#include<sqltypes.h>
#include <iostream>
#include<string>
#include <iomanip>
using namespace std;
//定义全局变量
SQLRETURN ret = NULL;//返回信息
SQLHENV henv = NULL;//环境句柄
SQLHDBC hdbc = NULL;//连接句柄
SQLHSTMT hstmt = NULL;//语句句柄
4.数据库连接函数
具体代码实现如下:
void connect()//数据库连接函数
{
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);//申请环境
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);//设置环境
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);//申请数据库连接
ret = SQLConnect(hdbc, (SQLTCHAR*)("SQL SERVER"), SQL_NTS, (SQLTCHAR*)("sa"), SQL_NTS, (SQLTCHAR*)("72580."), SQL_NTS);
if ((ret == SQL_SUCCESS) || (ret == SQL_SUCCESS_WITH_INFO))
{
cout << "数据库连接成功!" << endl;
}
else
{
cout << "数据库连接失败!" << endl;
}
}
你们要把SQLConnect函数的几个参数修改一下:
1.“SQL SERVER”,要改成你所设置的ODBC数据源名称,如果不知道ODBC数据源名称是什么,具体可看我配置ODBC的文章。
2."sa"改成你SQL Server 的登录名。
3."72580."改成你SQL Server的登录密码。
5.插入操作(insert)
这里以上架书籍为例,即在表Books中插入一条记录,具体实现代码如下:
void insert_book()
{
// sql语句:insert into Books values ('001','计算机网络',10)
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";//第一句要执行的SQL语句
string str2 = "insert into Books values ('";//第二句要执行的SQL语句
cout << "请依次输入图书编号、图书名称、图书数量" << endl;
string Bno, Bname, Bsum;
cin >> Bno >> Bname >> Bsum;
string str3=str2 + Bno + "','" + Bname + "'," + Bsum + ")";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
cout << "书籍上架成功!" << endl;
}
else {
cout << "书籍上架失败!" << endl;
}
free();
}
6.删除操作(delete)
这里以下架书籍为例,即删除表Books中的一条记录,具体实现代码如下:
void delete_book()
{
//sql语句:delete Books where Bname='计算机网络'
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "delete Books where Bname='";
cout << "请下输入架书籍名称" << endl;
string Bname;
cin >> Bname;
string str3 = str2 + Bname + "'";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
cout << "书籍下架成功!" << endl;
}
else {
cout << "书籍下架失败!" << endl;
}
free();
}
7.修改操作(update)
这里以借书为例,具体借书函数代码实现如下:
void borrow_book()
{
cout << "请输入你的学号" << endl;
string Sno;
cin >> Sno;
cout << "请输入你想借的书籍名称" << endl;
string Bname;
cin >> Bname;
if (getbsum(Bname) > 0)//为了判断是否能借书,这里自定义了一个能够获取图书数量bsum的函数getbsum(string bname)
{
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "update Books set Bsum-=1 where Bname='";
string str3 = str2 + Bname + "'";
string str4 = "declare @a char(6) select @a=Bno from Books where Bname= '";
string str5 = str4 + Bname + "' insert into Record values ('" + Sno + "','借书',getdate(),@a)";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str5.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
cout << "借书成功!" << endl;
else
cout << "借书失败!" << endl;
}
else
cout << "此书库存不足,无法借阅" << endl;
free();
}
8.查询操作(select)
这里以查找书籍信息为例,具体实现代码如下:
void query_book()
{
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "select *from Books where Bname='";
cout << "请输入书名" << endl;
string Bname;
cin >> Bname;
string str3 = str2 + Bname + "'";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
SQLCHAR str1[10], str2[12], str3[10];//用来存放从数据库获取的列信息,你有几列就定义几个变量
SQLINTEGER len_str1, len_str2, len_str3;//字符串对应长度,你有几列就定义几个变量
//printf("%s\t%s\t%s\n", "书籍编号", "书籍名称", "数量");
cout << "编号" << " " << "书籍名称" << " " << "书籍数量" << endl;
while (SQLFetch(hstmt) != SQL_NO_DATA)
{
//你有几列就调用几次SQLGetData函数,注意找规律哦
SQLGetData(hstmt, 1, SQL_C_CHAR, str1, 10, &len_str1); //获取第一列数据
SQLGetData(hstmt, 2, SQL_C_CHAR, str2, 12, &len_str2); //获取第二列数据
SQLGetData(hstmt, 3, SQL_C_CHAR, str3, 10, &len_str3); //获取第三列数据
printf("%s\t%s\t%s\n", str1,str2, str3);
}
}
free();
}
四、 源代码
#undef UNICODE
#undef _UNICODE
#include<Windows.h>
#include <sql.h>
#include <sqlext.h>
#include<sqltypes.h>
#include <iostream>
#include<string>
#include <iomanip>
using namespace std;
//定义全局变量
SQLRETURN ret = NULL;//返回信息
SQLHENV henv = NULL;//环境句柄
SQLHDBC hdbc = NULL;//连接句柄
SQLHSTMT hstmt = NULL;//语句句柄
//释放空间
void free()
{
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);//释放语句
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);//释放连接
SQLFreeHandle(SQL_HANDLE_ENV, henv);//释放环境
}
//连接数据库
void connect()//数据库连接函数
{
SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);//申请环境
SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER);//设置环境
SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);//申请数据库连接
ret = SQLConnect(hdbc, (SQLTCHAR*)("SQL SERVER"), SQL_NTS, (SQLTCHAR*)("sa"), SQL_NTS, (SQLTCHAR*)("72580."), SQL_NTS);
if ((ret == SQL_SUCCESS) || (ret == SQL_SUCCESS_WITH_INFO))
{
cout << "数据库连接成功!" << endl;
}
else
{
cout << "数据库连接失败!" << endl;
}
}
//获取书籍数量
int getbsum(string bname)
{
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string sql = "use JYXT";
string sql2 = "select bsum from Books where Bname='";
string str = sql2 + bname + "'";
ret = SQLExecDirect(hstmt, (SQLCHAR*)sql.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
int a=0;
string str1;
SQLINTEGER len_str1;
while (SQLFetch(hstmt) != SQL_NO_DATA)
{
SQLGetData(hstmt, 1, SQL_C_CHAR, (SQLCHAR*)str1.c_str(), 10, &len_str1); //获取第一列数据
a = atoi(str1.c_str());
}
free();
return a;
}
}
//借书(删除)
void borrow_book()
{
cout << "请输入你的学号" << endl;
string Sno;
cin >> Sno;
cout << "请输入你想借的书籍名称" << endl;
string Bname;
cin >> Bname;
if (getbsum(Bname) > 0)
{
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "update Books set Bsum-=1 where Bname='";
string str3 = str2 + Bname + "'";
string str4 = "declare @a char(6) select @a=Bno from Books where Bname= '";
string str5 = str4 + Bname + "' insert into Record values ('" + Sno + "','借书',getdate(),@a)";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str5.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
cout << "借书成功!" << endl;
else
cout << "借书失败!" << endl;
}
else
cout << "此书库存不足,无法借阅" << endl;
free();
}
//还书(增加)
void return_book()
{
cout << "请输入你的学号" << endl;
string Sno;
cin >> Sno;
cout << "请输入你要还的书籍名称" << endl;
string Bname;
cin >> Bname;
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "update Books set Bsum+=1 where Bname='";
string str3 = str2 + Bname + "'";
string str4 = "declare @a char(6) select @a=Bno from Books where Bname= '";
string str5 = str4 + Bname + "' insert into Record values ('" + Sno + "','还书',getdate(),@a)";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str5.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
cout << "还书成功!" << endl;
else
cout << "还书失败!" << endl;
free();
}
//查询学生借阅信息(查找)
void print_br()
{
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "SELECT*FROM Record where Sno='";
cout << "请输入学号" << endl;
string Sno;
cin >> Sno;
string str3 = str2 + Sno + "'";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
SQLCHAR str1[10], str2[12], str3[20], str4[20];
SQLINTEGER len_str1, len_str2, len_str3, len_str4;
//printf("%s\t%s\t%s\n", "书籍编号", "书籍名称", "数量");
cout << "学号" << " " << "操作" << " " << "操作时间" << " 图书编号"<<endl;
while (SQLFetch(hstmt) != SQL_NO_DATA)
{
SQLGetData(hstmt, 1, SQL_C_CHAR, str1, 10, &len_str1); //获取第一列数据
SQLGetData(hstmt, 2, SQL_C_CHAR, str2, 12, &len_str2);
SQLGetData(hstmt, 3, SQL_C_CHAR, str3, 20, &len_str3);
SQLGetData(hstmt, 4, SQL_C_CHAR, str4, 20, &len_str4);
printf("%s\t%s\t%s\t%s\n", str1, str2, str3, str4);
}
}
free();
}
//查询书籍信息(查找)
void query_book()
{
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "select *from Books where Bname='";
cout << "请输入书名" << endl;
string Bname;
cin >> Bname;
string str3 = str2 + Bname + "'";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
{
SQLCHAR str1[10], str2[12], str3[10];
SQLINTEGER len_str1, len_str2, len_str3;
//printf("%s\t%s\t%s\n", "书籍编号", "书籍名称", "数量");
cout << "编号" << " " << "书籍名称" << " " << "书籍数量" << endl;
while (SQLFetch(hstmt) != SQL_NO_DATA)
{
SQLGetData(hstmt, 1, SQL_C_CHAR, str1, 10, &len_str1); //获取第一列数据
SQLGetData(hstmt, 2, SQL_C_CHAR, str2, 12, &len_str2);
SQLGetData(hstmt, 3, SQL_C_CHAR, str3, 10, &len_str3);
printf("%s\t%s\t%s\n", str1,str2, str3);
}
}
free();
}
//上架书籍
void insert_book()
{
//insert into Books values ('006','计算机网络',10)
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "insert into Books values ('";
cout << "请依次输入图书编号、图书名称、图书数量" << endl;
string Bno, Bname, Bsum;
cin >> Bno >> Bname >> Bsum;
string str3=str2 + Bno + "','" + Bname + "'," + Bsum + ")";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
cout << "书籍上架成功!" << endl;
}
else {
cout << "书籍上架失败!" << endl;
}
free();
}
//下架书籍
void delete_book()
{
//delete Books where Bname='计算机网络'
ret = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);//申请句柄
string str1 = "use JYXT";
string str2 = "delete Books where Bname='";
cout << "请下输入架书籍名称" << endl;
string Bname;
cin >> Bname;
string str3 = str2 + Bname + "'";
ret = SQLExecDirect(hstmt, (SQLCHAR*)str1.c_str(), SQL_NTS);
ret = SQLExecDirect(hstmt, (SQLCHAR*)str3.c_str(), SQL_NTS);
if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) {
cout << "书籍下架成功!" << endl;
}
else {
cout << "书籍下架失败!" << endl;
}
free();
}
int main()
{
return 0;
}
更多推荐
C++通过ODBC方式连接数据库SQLServer及增删查改操作【图书借阅系统为例】
发布评论