ADO在这里就不细述了,直接讲解访问的过程。
#pragma once #include<iostream> #include <cassert> #include <string> #include <ATLComTime.h> //为了COleDateTime类引入 using namespace std; //这是引入ADO动态链接库,默认的路径如下,如果不在默认地方,在这里需要另外指明位置 #import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF", "adoEOF") //以下类是为了其余人使用的方便做了一个简单的封装 class MyDateTime { public: MyDateTime(); MyDateTime(COleDateTime oleDateTime); MyDateTime(int year, int month, int day, int hour, int minute, int second); ~MyDateTime(); void SetDateTime(COleDateTime oleDateTime); void SetMyDate(int year, int month, int day); void SetMyTime(int hour, int minute, int second); int GetYear(); int GetMonth(); int GetDay(); int GetHour(); int GetMinute(); int GetSecond(); void CurrentDateTime(); private: COleDateTime m_oleDateTime; }; class CppSQLDB { public: ~CppSQLDB(); //执行一些非查询类的语句,如insert delete update void ExecuteDML(string strSql); //执行带有返回记录集的查询类语句,insert into void ExectueQuery(string strSql); void SetFirstRow(); //这三个都是_RecordsetPtr对象拥有的函数,对外封装一层而已 bool Eof(); void NextRecord(); bool IsExist(string tablename, string fieldname, string value); void GetIntValue(int nField, int &rInt); void GetIntValue(string szField, int &rInt); void GetFloatValue(int nField, float &rFloat); void GetFloatValue(string szField, float &rFloat); void GetStringValue(int nField, string &rString); void GetStringValue(string szField, string &rString); void GetCharArrValue(int nField, char *&rChar); void GetCharArrValue(string szField, char *&rChar); void GetDateTimeValue(int nField, MyDateTime &mdt); void GetDateTimeValue(string szField, MyDateTime &mdt); bool IsLegalUser(string loginname, string password); bool IsExistUser(string loginname, string password); public: static CppSQLDB *m_sMe; static CppSQLDB* GetMe() { if(m_sMe == NULL) { m_sMe = new(std::nothrow) CppSQLDB(); assert(m_sMe != NULL); } return m_sMe; } private: //将其构造函数设置成私有的,防止外部程序私自建立单例模式的对象,从类本身出发控制了实例的数目 CppSQLDB(); _ConnectionPtr m_pConnection; _CommandPtr m_pCommand; _RecordsetPtr m_pRecordSet; };
#include "CppSQLServer.h" /////////////////////////////////////////////////////// //MyDateTime类 ////////////////////////////////////////////////////// MyDateTime::MyDateTime() { } MyDateTime::MyDateTime(COleDateTime oleDateTime) { m_oleDateTime = oleDateTime; } MyDateTime::MyDateTime(int year, int month, int day, int hour, int minute, int second) { m_oleDateTime.SetDate(year, month, day); m_oleDateTime.SetTime(hour, minute, second); } MyDateTime::~MyDateTime() { } void MyDateTime::SetDateTime(COleDateTime oleDateTime) { m_oleDateTime = oleDateTime; } void MyDateTime::SetMyDate(int year, int month, int day) { m_oleDateTime.SetDate(year, month, day); } void MyDateTime::SetMyTime(int hour, int minute, int second) { m_oleDateTime.SetTime(hour, minute, second); } int MyDateTime::GetYear() { return m_oleDateTime.GetYear(); } int MyDateTime::GetMonth() { return m_oleDateTime.GetMonth(); } int MyDateTime::GetDay() { return m_oleDateTime.GetDay(); } int MyDateTime::GetHour() { return m_oleDateTime.GetHour(); } int MyDateTime::GetMinute() { return m_oleDateTime.GetMinute(); } int MyDateTime::GetSecond() { return m_oleDateTime.GetSecond(); } void MyDateTime::CurrentDateTime() { m_oleDateTime = COleDateTime::GetCurrentTime(); } //********************************************************************** //CppSQLServer类 //静态成员初始化 CppSQLDB* CppSQLDB::m_sMe = NULL; CppSQLDB::CppSQLDB() { CoInitialize(NULL); //初始化COM //初始化_ConnectionPtr指针对象实例 //在这个地方最好多用扑捉异常,因为一旦在整个访问过程中出了错就会出现一样的运行不下去,根本不知道哪里出错了 //使用异常后就会很快知道哪里出的问题 HRESULT hr; //以下三个指针均为智能指针,所以不必担心有开辟没释放而导致的内存泄露问题 hr = m_pConnection.CreateInstance(__uuidof(Connection)); if(FAILED(hr)) { cout<<"_ConnectionPtr对象指针实例化失败!!!"<<endl; } else { try { //连接语句,一般格式是固定的 //后面三个参数是 混合验证模式下登陆账号与密码(SQL SERVER 2008默认的是Windows验证模式,所以需要改) 还有要访问的数据库名 _bstr_t strConnect="Driver={sql server};server=127.0.0.1,1433;uid=supercell;pwd=supercell;database=ZHY;"; m_pConnection->Open(strConnect, "", "", adModeUnknown); //建立连接 } catch(_com_error &e) { cout<<e.Description()<<endl; } } //初始化_CommandPtr指针对象实例 hr = m_pCommand.CreateInstance(__uuidof(Command)); if(FAILED(hr)) { cout<<"_CommandPtr对象指针实例化失败!!!"<<endl; } else { try { m_pCommand->ActiveConnection = m_pConnection; //为命令绑定连接对象 } catch(_com_error &e) { cout<<e.Description()<<endl; } } //初始化_RecordSetPtr指针对象实例 hr = m_pRecordSet.CreateInstance(__uuidof(Recordset)); if(FAILED(hr)) { cout<<"_RecordSetPtr对象指针实例化失败!!!"<<endl; } //把这个数据库访问类做成了单例模式,单例模式的 m_sMe = this; } CppSQLDB::~CppSQLDB() { if (m_pConnection->State) { m_pConnection->Close(); } if (m_pCommand->State) { m_pCommand->Release(); } if (m_pRecordSet->State) { m_pRecordSet->Close(); } } void CppSQLDB::ExecuteDML(string strSql) { try { m_pCommand->CommandText = _bstr_t(strSql.c_str()); m_pCommand->Execute(NULL, NULL, adCmdText); } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::ExectueQuery(string strSql) { try { m_pCommand->CommandText = _bstr_t(strSql.c_str()); m_pRecordSet = m_pCommand->Execute(NULL, NULL, adCmdText); } catch(_com_error &e) { cout<<e.Description()<<endl; } } bool CppSQLDB::Eof() { return (bool)m_pRecordSet->adoEOF; } void CppSQLDB::SetFirstRow() { m_pRecordSet->MoveFirst(); } void CppSQLDB::NextRecord() { m_pRecordSet->MoveNext(); } bool CppSQLDB::IsExist(string tablename, string fieldname, string value) { char strSql[128] = { 0 }; sprintf_s(strSql, 128, "select count(*) from %s where %s = '%s'", tablename, fieldname, value); _variant_t var; int valueNums; try { m_pCommand->CommandText = _bstr_t(strSql); m_pRecordSet = m_pCommand->Execute(NULL, NULL, adCmdText); m_pRecordSet->MoveFirst(); var = m_pRecordSet->GetCollect(_variant_t(long(0))); var.vt = VT_I4; valueNums = var; } catch(_com_error &e) { cout<<e.Description()<<endl; } if (valueNums > 0) { return true; } else { return false; } } void CppSQLDB::GetIntValue(int nField, int &rInt) { _variant_t var; try { var = (m_pRecordSet->GetCollect(_variant_t(long(nField)))); var.ChangeType(VT_I4); //转换数据类型为int rInt = var; } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetIntValue(string szField, int &rInt) { _variant_t var; try { var = (m_pRecordSet->GetCollect(szField.c_str())); var.ChangeType(VT_I4); rInt = var; } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetFloatValue(int nField, float &rFloat) { _variant_t var; try { var = (m_pRecordSet->GetCollect(_variant_t(long(nField)))); var.ChangeType(VT_R4); //float rFloat = var; } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetFloatValue(string szField, float &rFloat) { _variant_t var; try { var = (m_pRecordSet->GetCollect(szField.c_str())); var.ChangeType(VT_R4); rFloat = var; } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetStringValue(int nField, string &rString) { try { rString = (char*)(_bstr_t)(m_pRecordSet->GetCollect(_variant_t(long(nField)))); //string类型转换形式不同 } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetStringValue(string szField, string &rString) { try { rString = (char*)(_bstr_t)(m_pRecordSet->GetCollect(szField.c_str())); } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetCharArrValue(int nField, char *&rChar) { string strTemp; try { strTemp = (char*)(_bstr_t)(m_pRecordSet->GetCollect(_variant_t(long(nField)))); strcpy_s(rChar, strTemp.length()+1, strTemp.c_str()); } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetCharArrValue(string szField, char *&rChar) { string strTemp; try { strTemp = (char*)(_bstr_t)(m_pRecordSet->GetCollect(szField.c_str())); strcpy_s(rChar, strTemp.length()+1, strTemp.c_str()); } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetDateTimeValue(int nField, MyDateTime &mdt) { _variant_t var; COleDateTime dt; try { var = (m_pRecordSet->GetCollect(_variant_t(long(nField)))); var.ChangeType(VT_DATE); //ADO接口从数据库中返回的日期类型格式与ATL中COleDateTime正好匹配 dt = var; mdt.SetDateTime(dt); } catch(_com_error &e) { cout<<e.Description()<<endl; } } void CppSQLDB::GetDateTimeValue(string szField, MyDateTime &mdt) { _variant_t var; COleDateTime dt; try { var = (m_pRecordSet->GetCollect(szField.c_str())); var.ChangeType(VT_DATE); //以上VT_****均为MSDN中已定义好的一些VT_TYPE类型 dt = var; mdt.SetDateTime(dt); } catch(_com_error &e) { cout<<e.Description()<<endl; } } bool CppSQLDB::IsLegalUser(string loginname, string password) { return IsExistUser(loginname, password); } //为了验证登陆用户的合法性 bool CppSQLDB::IsExistUser(string loginname, string password) { char strSql[128] = { 0 }; sprintf_s(strSql, 128, "select count(*) from UserInfor where uNo = '%s' and uPW = '%s'", loginname.c_str(), password.c_str()); _variant_t var; int valueNums; try { m_pCommand->CommandText = _bstr_t(strSql); m_pRecordSet = m_pCommand->Execute(NULL, NULL, adCmdText); m_pRecordSet->MoveFirst(); //移至数据集的第一行 var = m_pRecordSet->GetCollect(_variant_t(long(0))); //获取第一个字段的值(就是返回的目标记录行数) var.vt = VT_I4; valueNums = var; } catch(_com_error &e) { cout<<e.Description()<<endl; } if (valueNums > 0)//存在该目标用户 { return true; } else { return false; } } //**********************************************************
关于SQL SERVER 2008登陆验证模式的修改:点击打开链接
代码连带整个工程均在我的资源里,请需要的自行下载
以下为一个使用用例
#include "CppSQLServer.h" int main() { //测试插入一条记录 // char szSql[128] = { 0 }; // MyDateTime mdt; //声明一个自定义日期时间类 // mdt.CurrentDateTime(); //获取当前时间,存储在内部变量中,无返回值 // //下面一条语句展示了如何获取当前的年月日等信息,返回的均是int // sprintf_s(szSql, 128, "insert into UserInfor values('%s', '%s', '%d-%d-%d');", "HAHAHA", "HAHAHA", mdt.GetYear(), mdt.GetMonth(), mdt.GetDay()); // CppSQLDB::GetMe()->ExecuteDML(szSql); //测试带有返回结果集的查询类 char szSql[128] = { 0 }; sprintf_s(szSql, 128, "select * from Student where Sage = '21';"); CppSQLDB::GetMe()->ExectueQuery(szSql); //传进查询语句,结果集保存在内部的ADO变量中,无返回 int no; float age; string name; MyDateTime mdt; CppSQLDB::GetMe()->SetFirstRow(); //在每一次新的查询后都要先设置记录集指针指向第一行记录,才可以遍历记录集 while (!CppSQLDB::GetMe()->Eof()) { CppSQLDB::GetMe()->GetIntValue("Sno", no); //以字段名作为查询参数 CppSQLDB::GetMe()->GetStringValue(1, name); //以列索引(从0开始)作为查询参数 CppSQLDB::GetMe()->GetFloatValue("Sage", age); CppSQLDB::GetMe()->GetDateTimeValue(5, mdt); CppSQLDB::GetMe()->NextRecord(); //每获取一条记录后都要将记录集指针后移一行 cout<<no<<" "<<name<<" "<<age<<" "<<mdt.GetYear()<<"-"<<mdt.GetMonth()<<"-"<<mdt.GetDay()<<endl; } //测试登陆账号密码合法性 bool flag = CppSQLDB::GetMe()->IsLegalUser("zhaohaoyang", "zhaohaoyang"); if (flag) { cout<<"合法用户"<<endl; } else { cout<<"非法用户"<<endl; } return 0; }