1. 前言
在软件开发过程中,连接数据库是必不可少的一部分。本文将介绍如何在MFC程序中连接Microsoft SQL Server数据库,并提出了一种完美的方案。
2. MFC连接MSSQL数据库的传统方法
在传统的MFC程序中,连接数据库通常使用ADODB技术。下面是一段MFC连接MSSQL数据库的代码:
CString strConnection;
strConnection.Format(_T("Provider=SQLOLEDB;Data Source=%s;Initial Catalog=%s;Uid=%s;Pwd=%s;"),
_T("localhost"),
_T("testdb"),
_T("sa"),
_T("123456"));
_ConnectionPtr spConnection;
HRESULT hr;
hr = spConnection.CreateInstance(__uuidof(Connection));
if (SUCCEEDED(hr))
{
hr = spConnection->Open(_bstr_t(strConnection), _T(""), _T(""), adConnectUnspecified);
}
if (SUCCEEDED(hr))
{
// Success
}
else
{
// Failure
}
上面的代码虽然可以连接MSSQL数据库,但是需要额外安装ADODB技术支持,而且很容易出现各种问题。在64位的操作系统中运行32位的程序时,可能会出现Class not registered的错误。同时,如果我们想更加深入的了解数据库操作的底层,ADODB不是很友好。
3. 完美的方案
尽管程序员可以使用ODBC技术来连接数据库,但是ODBC编程的艰难度和复杂性仍然是所有MFC数据方案中最高的。Owing to that, Microsoft has created a very powerful and very easy to use library for data access which is ADO.NET.
ADO.NET在连接数据库方面提供了一种完美的解决方案,我们可以使用它来连接多种数据库,包括MSSQL、Oracle、MySQL等。它特别适合于通过C++进行编程并连接MSSQL数据库。因此,本文提出的完美方案是使用ADO.NET连接MSSQL数据库。
3.1. 安装SQL Server Native Client
在使用ADO.NET连接MSSQL数据库之前,需要先安装SQL Server Native Client。这是一个可选组件,在Microsoft官方网站下载并安装即可。安装完成后,即可使用ADO.NET连接MSSQL数据库。
3.2. 引用必要的命名空间
为了使用ADO.NET连接数据库,首先需要添加以下命名空间:
#include <windows.h>
#include <sqltypes.h>
#include <sql.h>
#include <sqlext.h>
#include <sqlucode.h>
#include <string>
#include <vector>
#include <atlstr.h>
#include <comutil.h>
#include <atlcomtime.h>
#include <msclr/marshal.h>
#include <msclr/marshal_cppstd.h>
using namespace System::Data::SqlClient;
using namespace System::Data;
using namespace System;
using namespace msclr::interop;
3.3. 连接数据库
使用ADO.NET连接MSSQL数据库的代码如下所示:
String^ connetionString = "Data Source=(local);Initial Catalog=testdb;Integrated Security=True";
SqlConnection^ connection = gcnew SqlConnection(connetionString);
try
{
connection->Open();
// 成功连接数据库
}
catch (SqlException^ ex)
{
// 连接数据库失败
}
finally
{
connection->Close();
}
上述代码创建一个SqlConnection对象,并传递连接字符串作为构造函数的参数。然后,它使用Open()方法打开数据库连接。如果连接成功,就可以执行数据库操作。如果连接失败,可以使用错误信息(在SqlException对象中包含)来诊断问题。
3.4. 执行SQL查询
可以使用SqlCommand类在MFC程序中执行SQL查询。下面是一个例子:
String^ connetionString = "Data Source=(local);Initial Catalog=testdb;Integrated Security=True";
SqlConnection^ connection = gcnew SqlConnection(connetionString);
try
{
connection->Open();
String^ sql = "SELECT * from users";
SqlCommand^ command = gcnew SqlCommand(sql, connection);
SqlDataReader^ reader = command->ExecuteReader();
while (reader->Read())
{
String^ id = reader->GetInt32(0).ToString();
String^ name = reader->GetString(1);
// 处理查询结果
}
reader->Close();
}
catch (SqlException^ ex)
{
// 连接数据库失败
}
finally
{
connection->Close();
}
上面的代码执行SELECT * FROM users查询,并使用SqlCommand类的ExecuteReader()方法执行查询。如果查询成功,可以从SqlDataReader对象中获取查询结果,并进行相应的处理。
3.5. 插入和更新数据
对于插入和更新数据操作,可以使用SqlCommand类的ExecuteNonQuery()方法。下面是一个例子:
String^ connetionString = "Data Source=(local);Initial Catalog=testdb;Integrated Security=True";
SqlConnection^ connection = gcnew SqlConnection(connetionString);
try
{
connection->Open();
String^ sql = "INSERT INTO users (name,age) VALUES ('张三',22)";
SqlCommand^ command = gcnew SqlCommand(sql, connection);
int nRows = command->ExecuteNonQuery();
// 处理插入操作结果
sql = "UPDATE users SET age = 23 WHERE id = 1";
command = gcnew SqlCommand(sql, connection);
nRows = command->ExecuteNonQuery();
// 处理更新操作结果
}
catch (SqlException^ ex)
{
// 连接数据库失败
}
finally
{
connection->Close();
}
上述代码插入一条新用户记录,并使用UPDATE语句更新id为1的用户年龄。对于插入和更新操作都可以使用ExecuteNonQuery()方法获取受影响的行数,并进行相应的处理。
3.6. 使用事务处理多条SQL语句
ADO.NET允许使用事务处理多条SQL语句。如果一个SQL语句失败,那么整个事务将被回滚。下面是一个例子:
String^ connetionString = "Data Source=(local);Initial Catalog=testdb;Integrated Security=True";
SqlConnection^ connection = gcnew SqlConnection(connetionString);
SqlCommand^ command1, ^command2;
SqlTransaction^ tran = nullptr;
try
{
connection->Open();
tran = connection->BeginTransaction();
command1 = gcnew SqlCommand("INSERT INTO dept (name) VALUES ('研发部')", connection, tran);
command2 = gcnew SqlCommand("UPDATE users SET dept = '研发部' WHERE id IN (1,2)", connection, tran);
int nRows1 = command1->ExecuteNonQuery();
int nRows2 = command2->ExecuteNonQuery();
// 处理事务操作结果
tran->Commit();
}
catch (SqlException^ ex)
{
// 事务回滚
tran->Rollback();
}
finally
{
connection->Close();
}
上述代码使用BeginTransaction()方法开启一个事务,并在两个SQL语句中使用同一个SqlTransaction对象。如果两个SQL语句都执行成功,调用Commit()方法提交事务。否则,调用Rollback()方法回滚。
4. 总结
本文介绍了连接MSSQL数据库的完美方案,并提供了使用ADO.NET连接MSSQL数据库的范例代码。ADO.NET代码相对于ADODB代码来说更为简单、易懂、易调试,同时也更加灵活和可扩展。尤其是在64位操作系统中运行32位程序时,ADO.NET表现更加出色。希望本文可以帮助广大程序员更快、更好地开发MFC程序。