会话事务对象的创建
※ 在拥有了数据源对象之后,通过已有接口Query出IDBCreateSession接口
※然后调用IDBCreateSession::CreateSession方法创建一个Session对象接口,也即创建一个新的Session对象。
※需要注意的是一个数据源对象可以用来创建多个Session对象及接口,创建多少个一般没有限制
※这里要注意的是不能用CoCreateInstance标准方法来创建Session对象及接口
※这种创建新的对象和接口的方式也是对COM规范本身的扩展,是一种基于COM设计系统时的扩展设计模式
※默认的Session对象的事务隔离级别是自动提交级别(为进一步确定可调用ISessionProperties::GetProperties来检查)
※为了能够正常进行后续的处理任务,一般应用中至少应创建一个Session对象(很多简单的应用中创建一个就够用了)
#include <tchar.h>
#include <windows.h>
#include <strsafe.h>
#define COM_NO_WINDOWS_H //如果已经包含了Windows.h或不使用其他Windows库函数时
#define DBINITCONSTANTS
#define INITGUID
#define OLEDBVER 0x0260 //为了ICommandStream接口定义为2.6版
#include <oledb.h>
#include <oledberr.h>
#include <msdasc.h>
#define GRS_ALLOC(sz) HeapAlloc(GetProcessHeap(),0,sz)
#define GRS_CALLOC(sz) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sz)
#define GRS_SAFEFREE(p) if(NULL != p){HeapFree(GetProcessHeap(),0,p);p=NULL;}
#define GRS_USEPRINTF() TCHAR pBuf[1024] = {}
#define GRS_PRINTF(...) \
StringCchPrintf(pBuf,1024,__VA_ARGS__);\
WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),pBuf,lstrlen(pBuf),NULL,NULL);
#define GRS_SAFERELEASE(I) if(NULL != I){I->Release();I=NULL;}
#define GRS_COM_CHECK(hr,...) if(FAILED(hr)){GRS_PRINTF(__VA_ARGS__);goto CLEAR_UP;}
#define GRS_DEF_INTERFACE(i) i* p##i = NULL;
#define GRS_QUERYINTERFACE(i,iid) \
if(FAILED(hr = i->QueryInterface(IID_##iid, (void **)&p##iid)) )\
{\
GRS_PRINTF(_T("不支持'%s'接口\n"),_T(#iid));\
}\
else\
{\
GRS_PRINTF(_T("支持'%s'接口\n"),_T(#iid));\
}\
GRS_SAFERELEASE(p##iid);
BOOL DlgConnectDB(IDBInitialize* &PDBConnect);
int _tmain()
{
GRS_USEPRINTF();
CoInitialize(NULL);//初始化com环境
HRESULT hr=S_OK;
IDBInitialize* pIDBConnect =NULL; //数据库初始化 数据源对象的接口
IDBCreateSession* pIDCreateSession=NULL;
GRS_DEF_INTERFACE(IGetDataSource);
GRS_DEF_INTERFACE(IOpenRowset);
GRS_DEF_INTERFACE(ISessionProperties);
GRS_DEF_INTERFACE(IAlterIndex);
GRS_DEF_INTERFACE(IAlterTable);
GRS_DEF_INTERFACE(IBindResource);
GRS_DEF_INTERFACE(IConnectionPointContainer);
GRS_DEF_INTERFACE(ICreateRow);
GRS_DEF_INTERFACE(IDBCreateCommand);
GRS_DEF_INTERFACE(IDBSchemaRowset);
GRS_DEF_INTERFACE(IIndexDefinition);
GRS_DEF_INTERFACE(ISupportErrorInfo);
GRS_DEF_INTERFACE(ITableCreation);
GRS_DEF_INTERFACE(ITableDefinition);
GRS_DEF_INTERFACE(ITableDefinitionWithConstraints);
GRS_DEF_INTERFACE(ITransaction);
GRS_DEF_INTERFACE(ITransactionJoin);
GRS_DEF_INTERFACE(ITransactionLocal);
GRS_DEF_INTERFACE(ITransactionObject);
if (!DlgConnectDB(pIDBConnect))
{
_tsystem(_T("PAUSE"));
return 0;
}
//首先从连接对象接口找到等价的CreateSession接口
hr=pIDBConnect->QueryInterface(IID_IDBCreateSession,(void**)&pIDCreateSession);
GRS_COM_CHECK(hr,_T("获取IDBCreateSession接口失败"));
//创建一个IOpenRowSet接口
hr=pIDCreateSession->CreateSession(NULL,IID_IOpenRowset,(IUnknown**)&pIOpenRowset);
GRS_COM_CHECK(hr,_T("创建IOpenRowset接口失败"));
GRS_PRINTF(_T("成功"));
GRS_SAFERELEASE(pIDCreateSession);
CLEAR_UP:
GRS_SAFERELEASE(pIOpenRowset);
GRS_SAFERELEASE(pIDCreateSession);
GRS_SAFERELEASE(pIDBConnect);
_tsystem(_T("PAUSE"));
CoUninitialize();
return 0;
}
BOOL DlgConnectDB(IDBInitialize* &PDBConnect)
{
GRS_USEPRINTF();
GRS_SAFERELEASE(PDBConnect);
IDBPromptInitialize* pIDBPromptInitialize=NULL;
HWND hWndParen=GetDesktopWindow();
CLSID clsid={};
//1使用OLEDB数据库连接对话框连接到数据源
HRESULT hr=CoCreateInstance(CLSID_DataLinks,NULL,CLSCTX_INPROC_SERVER,
IID_IDBPromptInitialize,(void**)&pIDBPromptInitialize);
if (FAILED(hr))
{
GRS_PRINTF(_T("无法创建IDBPromptInitialize接口"));
GRS_SAFERELEASE(PDBConnect);
GRS_SAFERELEASE(pIDBPromptInitialize);
return FALSE;
}
//下面的这句对话框弹出数据库连接对话框
hr=pIDBPromptInitialize->PromptDataSource(NULL,hWndParen,
DBPROMPTOPTIONS_PROPERTYSHEET,0,NULL,NULL,IID_IDBInitialize,(IUnknown**)&PDBConnect);
if (FAILED(hr))
{
GRS_PRINTF(_T("无法创建IDBPromptInitialize接口"));
GRS_SAFERELEASE(PDBConnect);
GRS_SAFERELEASE(pIDBPromptInitialize);
return FALSE;
}
GRS_SAFERELEASE(pIDBPromptInitialize);
hr=PDBConnect->Initialize();//根据对话框采集的参数连接到指定的数据库
if (FAILED(hr))
{
GRS_PRINTF(_T("初始化数据源链接错误。"));
GRS_SAFERELEASE(PDBConnect);
return FALSE;
}
return TRUE;
}
把连接数据源封装到 DlgConnectDB函数中了。