【C++】C++连接SQL Server 2014

01、文章目录

02、前言

SQL Server数据库,对大家应该都不陌生,如果你是计算机专业,可能在学校接触的第一种数据库就是他,因为他是很久以前流行的数据库,在他火的时候,还没有MySQLRedis等。

SQL Server 是一个关系数据库管理系统。它最初是由Microsoft、Sybase 和Ashton-Tate三家公司共同开发的,于1988 年推出了第一个OS/2版本。在Windows NT 推出后,Microsoft与Sybase 在SQL Server 的开发上就分道扬镳了,Microsoft 将SQL Server移植到Windows NT系统上,专注于开发推广SQL Server 的Windows NT 版本。Sybase 则较专注于SQL Server在UNⅨ操作系统上的应用。

SQL Server 2000 是Microsoft 公司推出的SQL Server数据库管理系统,该版本继承了SQL Server 7.0 版本的优点,同时又比它增加了许多更先进的功能。具有使用方便可伸缩性好与相关软件集成
程度高等优点,可跨越从运行Microsoft Windows 98 的膝上型电脑到运行Microsoft Windows 2000 的大型多处理器的服务器等多种平台使用。

当然,现在还在用SQL Server的基本上是一些老项目了,只所以出这篇文章,就是因为这方面的资料现在很少,记录一下,自己从0到完成项目需求的过程。希望能给正在做这方面的你给一些建议。

03、C++连接SQL Server方式

1. ODBC
ODBC(Open DataBase Connectivity)开放数据库互联。是由微软主导的数据库链接标准;

ODBC是一个访问数据库的底层接口,想要使用ODBC必须提供驱动,sqlserver 提供SQL Server Native Client ODBC driver来支持ODBC接口。

只能用户关系型数据库,很难用于对象数据库及其他非对象数据库。

ODBC访问sqlserver有一个好处,可以在linux上使用。linux上可以使用FreeTDS作为sqlserver的ODBC驱动。

2. DAO
DAO(Data Access Object)数据访问对象。不提供远程访问功能。

3. RDO
RDO(Remote Data Object)远程数据对象。速度快,支持SQL Server存储过程,同DAO一样是发展很多年了的技术。

4. OLE DB
OLE-DB(Object Linking and Embedding DataBase)对象链接和嵌入数据库。它依赖于COM和提供OLE DB提供者的厂商而非ODBC使用的SQL。

OLEDB则只能在windows上运行

5. ADO
ADO(ActiveX Data Object)活动数据对象。基于OLE-DB建立连接的局部和远程数据库访问技术。

ADO是OLEDB的封装,使用起来比OLEDB方便。由于ADO比OLEDB多了一层,其速度可能不及OLEDB

使用中,我们一般用OLE-DB和ADO替代DAO和RDO。

6. MFC(Microsoft Foundation Class)微软基础类。
MFC ODBC是对ODBC的封装。

这里我简单说了下区别,下面两篇博客是对上述的具体阐述,感兴趣可以看看。

http://blog.csdn.net/frank_liuxing/article/details/43231233

http://blog.csdn.net/ithomer/article/details/6624684

04、C++连接SQL Server步骤

由于我负责的项目中,客户使用的是SQL Server 2014,所以,我这边做MES系统,需要和他对接,所以,以SQL Server 2014连接为例:

4.1 C++与SQL 连接初始化

在你的项目中找到头文件stdafx.h 然后引入ADO连接方式。
具体代码如下:

#import “c:\Program Files\Common Files\System\ado\msado15.dll” 
no_namespace rename(EOF, “adoEOF”) rename(”BOF”, “adoBOF”) 
4.2 封装C++连接SQL类

这里我说下,这个不是必要的,只是我觉得既然用C++,最好是面向对象,封装为类,更加符合你用的语言,还有一点就是看着简洁一些。

下面我贴上我的代码段,这里只是核心代码,不包含公司与此类无关代码。

4.2.1 CDataBase.h
class CDataBase
{
public:
	CDataBase(); //标准构造函数
	~CDataBase();

public:
	BOOL InitiaiConn();  //连接SQL Server数据库
	BOOL ExitConn();   //断开SQL Server数据库
	_RecordsetPtr GetRecordSet(CString bstrSqlCmd); //获得记录集
	_RecordsetPtr ExcuteCmd(CString strCmd); //执行sql语句
	BOOL GroupData(CString sQRCode, CTime nData, CString sMachineNo); //组合sql语句
	void GetValues(CString strIP, CString strDBName, CString strDBLgName, CString strDBLgPwd,CString strDBTabName);  //这里是界面动态加载的参数设置
	BOOL CDataBase::TransitionResultToContain(_RecordsetPtr result, vector<CString>& buf);

private:
	_bstr_t m_bstrConn; //存储连接数据库的字符串
	_bstr_t m_sqlCmd; //存储sql语句
	_ConnectionPtr m_pConnection; //连接数据库对象指针
	_RecordsetPtr m_pRecordset;  //数据集对象指针

//下面忽略部分变量,涉及到公司其他版块,这里不写
}
4.2.2 CDataBase.cpp
  • 构造函数
CDataBase::CDataBase()
{
	//指针真可怕,使用必须初始化
	m_pConnection = NULL;
	m_pRecordset = NULL;
}
  • 析构函数
CDataBase::~CDataBase()
{
	//断开数据库连接,清理内存
	if(m_pConnection != NULL)
	{
		m_pConnection = NULL;
	}
	if(m_pRecordset != NULL)
	{
		m_pRecordset = NULL;
	}
}
  • 初始化(连接数据库)
BOOL CDataBase::InitiaiConn()
{
	//初始化COM库组件
	::CoInitialize(NULL);
	HRESULT hr = NULL;

	try
	{
		hr = m_pConnection.CreateInstance("ADODB.Connetion"); //创建Connection连接对象
		
		CString Constring; //组合连接串,这里也可以一步到位,但是就是写死了,不灵活。
		Constring = "Provider = SQLOLEDB.1;";
		Constring += "Password=" + m_strDBLgPwd + ";";
		Constring += "Persist Security Info = True;";
		Constring += "User ID=" + m_strDBLgName + ";";
		Constring += "Initial Catalog=" + m_strDBName + ";";
		Constring += "Data Source=" + m_strDBIP + ";";

		m_bstrConn = (_bstr_t)Constring;
	
		hr = m_pConnection->Open(m_bstrConn,L"",L"",adConnectUnspecified);
		if(!SUCCEEDED(hr))
		{
			AfxMessageBox("DataBase is failed.....");
			return FALSE;
		}
	}
	catch(_com_error e)
	{
		CString strErr;
		strErr.Format("DataBase is failed: %s\n",e.ErrorMessage());
		AfxMessageBox(strErr);
		return FALSE;
	}

	AfxMessageBox("DataBasee is successed!",MB_ICONINFORMATION);
	return TRUE;
}

这里我告诉大家一个小技巧,连接字符串不用自己写,自动生成步骤如下:

  1. 桌面新建一个文件夹,命名随意,后缀改为udl
  2. 打开此文件,选择提供程序,选择Microsoft OLE DB Provider SQL Server,点击下一步
  3. 连接选项,选择服务器名称,一般是一个地址,选择使用指定用户名称和密码,输入数据库登陆的密码和账号,允许保存密码勾选。在服务器上选择数据库则填数据库名。测试连接,连接ok,就说明环境没问题。
  4. 确定,保存此数据,回到桌面将udl改为txt。
  5. 打开txt,第3行则是你的连接串,前提是你要用这个udl能连接数据库,才能说明你的连接串没有问题。

如果环境是要两台pc或者远程互连,可以使用虚拟机,安装数据库,并实现此流程。虚拟机部分,后续我会出一章Tools专栏。

  • 断开数据库
BOOL CDataBase::ExitConn()
{
	//关闭记录集和连接
	if(m_pRecordset != NULL)
	{
		m_pRecordset->Close();
	}

	m_pConnection->Close();
	::CoUninitialize(); //可以理解为关闭COM库组件
	
	return TRUE;
}
  • 获得数据集
    功能:执行SQL语句,获得结果集
_RecordsetPtr CDataBase::GetRecordSet(CString bstrSqlCmd)
{
#if 0
m_pRecordset.CreateInstance(__uuidof(Recordset));
m_sqlCmd = _bstr_t(bstrSqlCmd);
//打开记录集
m_pRecordset->Open(m_sqlCmd, m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);

return m_pRecordset;
#else
if(FAILED(m_pRecordset.CreateInstance(__uuidof(Recordset)))
{
	return FALSE;
}
m_sqlCmd = _bstr_t(bstrSqlCmd);
try
{
	m_pRecodset->Open((_variant_t)m_sqlCmd,_variant_t((IDispatch*)m_pConnection),adOpenForwardOnly,adLockReadOnly,adOptionUnspecified);
}
catch(_com_error e)
{
	AfxMessageBox(e.Description()); //抛出的异常错误
	AfxMessageBox(GetLastError()); //调用系统最后一次发现的错误
}

return m_pRecordset();
#endif
}
  • 执行sql语句
    功能:执行存储过程,获得结果集
_RecordsetPtr CDatBase::ExcuteCmd(CString strCmd)
{
	//执行sql语句
	m_sqlCmd = _bstr_t(strCmd);

	try
	{
		m_pRecordset = m_pConnection->Execute(m_sqlCmd,NULL,adExecuteNoRecords);
	}
	catch(_com_error e)
	{
		CString strError;
		strError.Format("执行sql语句异常信息:%s\n",e.ErrorMessage());
		AfxMessageBox(e.ErrorMessage());
	}

	return m_pRecordset;
}
  • 组合sql语句(根据自己的实际要求组合,以下只是一个例子)
BOOL CDataBase::GroupData(CString sQRCode, CTime nDate, CString sMachineNo);
{
	CString strTmp2;
	m_sQRCode = sQRCode;
	m_sDate = nDate;
	m_sMachineNo = sMachineNo;
	
	strTmp2 = m_sDate.Format("%Y-%m-%d %H:%M:%S");

	CString str;
	str.Format("insert into "+ m_strTableName +"(ECODE,EDATE,ENO) values('"+  m_sQRCode +"','"+ strTmp2 +"','"+ m_sMachineNo +"')"); //组合一组插入数据

	ExcuteCmd(str);
	
	return TRUE;
}
  • 得到界面的数据信息
void CDataBase::GetValues(CString strIP, CString strDBName, CString strDBLgName, CString strDBLgPwd, CString strDBTabName)
{
   m_strDBIP = strIP;
   m_strDBName = strDBName;
   m_strDBLgName = strDBLgName;
   m_strDBLgPwd = strDBLgPwd;
   m_strTableName = strDBTabName;
}
  • 获取语句得到的全部值(遍历取值) 或者 存储过程(需研究)
BOOL CDataBase::TransitionResultToContain(_RecordsetPtr result, vector<CString>& buf)
{
	try
	{
		while(!result->adoEOF)
		{
			CString temp = (TCHAR*)(_bstr_t)result->GetFields()->GetItem("Value")->Value;
			AfxMessageBox(temp);  //将查询的值挨个输出
			buf.push_back(temp);
			result->MoveNext();
		}
	}
	catch (_com_error e)
	{
		CString strError;
		strError.Format("转换数据库记录到容器出错信息:%s\n",e.ErrorMessage());
		return FALSE;
	}

	return TRUE;
}

05、总结

关于C++连接SQL Server数据库的操作部分就说到这里吧。

上面的代码是经过二次更改的,所有连接程序和使用均已经用于实际工业生产,如有问题,请私聊或者下面评论,可能我回复没有那么及时,不是在出差就是在对接客户的需求,如果实在很急,请+微信:18523204389 ,备注来意,谢谢。

版权声明:转载请注明出处,谢谢!

  • 11
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
在C语言中使用ODBC连接SQL Server数据库,需要以下步骤: 1. 安装ODBC驱动程序:下载并安装Microsoft SQL Server ODBC驱动程序,使其能够被程序调用。 2. 初始化ODBC环境:使用SQLAllocHandle函数初始化ODBC环境,为后续的连接操作做准备。 3. 建立连接:使用SQLConnect函数连接SQL Server数据库,需要提供数据库的名称、用户名和密码等信息。 4. 执行SQL语句:使用SQLExecDirect函数执行SQL语句,可以是查询语句或更新语句等。 5. 处理结果:使用SQLBindCol函数绑定查询结果的每一列,然后使用SQLFetch函数获取每一行的数据。 6. 释放资源:使用SQLFreeStmt和SQLDisconnect函数释放连接和环境资源。 以下是一个使用ODBC连接SQL Server数据库的示例: ``` #include <stdio.h> #include <sql.h> #include <sqlext.h> int main(void) { SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt; SQLRETURN retcode; SQLCHAR szDSN[] = "myDSN"; SQLCHAR szUID[] = "myUser"; SQLCHAR szPWD[] = "myPassword"; SQLCHAR szConnStr[1024]; SQLCHAR szSqlStmt[1024]; SQLCHAR szCol1[256]; SQLCHAR szCol2[256]; SQLINTEGER iCol1; SQLINTEGER iCol2; // 初始化ODBC环境 retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); // 建立连接 sprintf(szConnStr, "DSN=%s;UID=%s;PWD=%s", szDSN, szUID, szPWD); retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); retcode = SQLDriverConnect(hdbc, NULL, szConnStr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE); // 执行SQL语句 sprintf(szSqlStmt, "SELECT col1, col2 FROM myTable"); retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); retcode = SQLExecDirect(hstmt, szSqlStmt, SQL_NTS); // 处理结果 retcode = SQLBindCol(hstmt, 1, SQL_C_CHAR, szCol1, sizeof(szCol1), NULL); retcode = SQLBindCol(hstmt, 2, SQL_C_LONG, &iCol2, 0, NULL); while (SQLFetch(hstmt) == SQL_SUCCESS) { printf("%s, %d\n", szCol1, iCol2); } // 释放资源 retcode = SQLFreeHandle(SQL_HANDLE_STMT, hstmt); retcode = SQLDisconnect(hdbc); retcode = SQLFreeHandle(SQL_HANDLE_DBC, hdbc); retcode = SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0; } ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cain Xcy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值