1. 程式人生 > >再探MFC(八)使用資料庫

再探MFC(八)使用資料庫

ADO包裝類

A set of ADO classes - version 2.20

使用介紹

CADODatabase包裝_ConnectionPtr,管理資料庫連線.

連線資料庫例子

//Sample withConnection string for SQL Server

CADODatabase* pAdoDb= new CADODatabase();

CStringstrConnection = _T("");

strConnection =_T("Provider=MSDASQL;PersistSecurityInfo=False;"

                  "Trusted_Connection=Yes;"

                   "Data Source=Access SqlServer;catalog=sampledb");

pAdoDb->SetConnectionString(strConnection);

if(pAdoDb->Open())

  DoSomething();

.

.

.

//Sample withConnection String for Access database

CADODatabase* pAdoDb= new CADODatabase();

CStringstrConnection = _T("");

strConnection =_T("Provider=Microsoft.Jet.OLEDB.4.0;"

              "DataSource=C:\\VCProjects\\ADO\\Test\\dbTest.mdb");

pAdoDb->SetConnectionString(strConnection);

if(pAdoDb->Open())

{

  DoSomething();

  .

  .

  .

  pAdoDb->Close();

}

delete pAdoDb;

注意如果是access 2007版本以上,請使用如下連線字串

strConnection =_T("Provider=Microsoft.Jet.OLEDB.12.0;")

_T("DataSource=simpledb.accdb;Persist Security Info=False");

CADORecordset包裝_RecordsetPtr,管理結果集.

執行SQL

  1. CADODatabase::Execute執行SQL語句.
  1. 直接用Recordset物件進行查詢取得記錄集.
  1. 利用command物件來執行SQL命令,command物件在進行儲存過程的呼叫中能真正體現它的作用

根據不同的目的執行不同的SQL方法.

CADORecordset* pRs =new CADORecordset(m_pDB);

TCHAR sql[256];

_stprintf_s(sql,sizeof(sql), _T("SELECT name,mobilephone FROM contacts"));

if(!pRs->Open(sql))

{

deletepRs;                

}

else

{

while(!pRs->IsEOF())

{

Contactcontact = Contact();

pRs->GetFieldValue(_T("name"),contact.name);

pRs->GetFieldValue(_T("mobilephone"),contact.mobilephone);

contacts.push_back(contact);

pRs->MoveNext();

}

pRs->Close();

deletepRs;

pRs= NULL;

}

引數

adCmdText:表明CommandText是文字命令

adCmdTable:表明CommandText是一個表名

adCmdProc:表明CommandText是一個儲存過程

adCmdUnknown:未知

_variant_tCOleDataTime轉換

CstringstrValue;

_variant_tvar;

If(var.vt==VT_DATA)

{

        DATA dt = var.data;

        COleDataTime da = COleDateTime(dt);

        strValue = da.Format("%Y-%m-%d%H:%M:%S");

}

BOFEOF

BOF、EOF 屬性

BOF 指示當前記錄位置位於Recordset 物件的第一個記錄之前。

EOF 指示當前記錄位置位於Recordset 物件的最後一個記錄之後。

常見問題

Broken ADO whencompiling at Windows 7 SP1

I have changed my adoImport.h file to meet specs ofKB2640696.

This solves the problem of broken ADO when compilingat Windows 7 SP1

to make it compatible to run on Windows Vista andWindows XP.

I include adoImport.h as first include in ado2.h andadox.h

//////////////////////////////////////////////////////////////////////////
//
// adoImport.h
//
// Header file for ado2.h and adox.h
//
// Created by Theo Buys, 27-4-2005
//
// Last revision:
//   $Author: Buys_t $
//     $Date: 4-09-12 12:41 $
// $Revision: 2 $
//
// msado15.dll has namespace ADODB
// msadox.dll has namespace ADOX
// msjro.dll has namespace JRO
//
/////////////////////////////////////////////////////////////////////////////

#if!defined(AFX_ADOIMPORT_H__A8F183D1_116B_4869_9125_16CFF9A03ADA__INCLUDED_)
#defineAFX_ADOIMPORT_H__A8F183D1_116B_4869_9125_16CFF9A03ADA__INCLUDED_
 
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <comdef.h>

#pragma message ( "***adoImport.h:" )
#pragma message ( "***Make sure you have set the library directory for msadox.dll, msado15.dll andmsjro.dll." )
#pragma message ( "***In Visual Studio 2010 go to" )
#pragma message ( "***View > Property Manager > Properties > Microsoft.Cpp.Win32.user >VC++ Directories > Library Directories")
#pragma message ( "***and add $(CommonProgramFiles)\\system\\ado")
 
// CG : In order to use this codeagainst a different version of ADO, the appropriate
// ADO library needs to be used in the #import statement

#import <msadox.dll>
 
/////////////////////////////////////////////////////////////////////////////
// msado15.dll and type libraries (.tlb) issues for building in Windows 7SP1
// see:
http://support.microsoft.com/kb/2640696
//
// 1) Consider the scenario where you are a C++ developer, and you include the
// following line of code in the application:
//
// #import <msado15.dll> rename("EOF","EndOfFile")
//
// 2) Consider the scenario that you recompile an application that must run in
// Windows Vista, in Windows Server 2008, or in later versions of Windows.
// And, you are not using MSJRO. In this scenario, you must change
// #import msado15.dll to the following:
//
// #import <msado60.tlb> rename("EOF","EndOfFile")
//
// 3) Consider the scenario that you are using MSJRO, and you recompile anapplication
// that must run in Windows Vista, in Windows Server 2008, or in a later
// version of Windows.
// 4) Consider the scenario that you recompile your application that must runin Windows XP
// or in Windows Server 2003. In both scenarios, you must change #importmsado15.dll
// to the following:
//
// #import <msado28.tlb> rename("EOF", "EndOfFile")

#import <msado28.tlb> rename("EOF", "EndOfFile")
 
/////////////////////////////////////////////////////////////////////////////
// msjro.dll issues
//
// #import <msjro.dll> no_namespace rename("ReplicaTypeEnum","_ReplicaTypeEnum")
//
// Enable the namespace and suppress warning C4336:
// import cross-referenced type library 'msado28.tlb' before importing'msjro.dll'

#import <msjro.dll> rename("ReplicaTypeEnum", "_ReplicaTypeEnum")
        
#endif //!defined(AFX_ADOIMPORT_H__A8F183D1_116B_4869_9125_16CFF9A03ADA__INCLUDED_)

Note that I haveenabled the namespace JRO.

I never put a"using namespace" statement in a header-file but only in asource-file.

I hope that this ishelpfull.

modified 4-Sep-12 7:46am.

VS2012 中編譯 C 語言專案,如果使用了 scanf 函式,編譯時便會提示如下錯誤:

error C4996: 'scanf': This function or variable may be unsafe. Considerusing scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. Seeonline help for details.

原因是VisualC++ 2012 使用了更加安全的 run-time library routines 。新的Security CRT functions(就是那些帶有“_s”字尾的函式),請參見:

下面給出這個問題的解決方案:

方法一:將原來的舊函式替換成新的 Security CRT functions

方法二:用以下方法遮蔽這個警告:

    1. 在預編譯標頭檔案stdafx.h裡(注意:一定要在沒有include任何標頭檔案之前)定義下面的巨集:

#define _CRT_SECURE_NO_DEPRECATE

    2. 或宣告#paramwarning(disable:4996)

    3. 更改預處理定義:

專案->屬性->配置屬性->C/C++ -> 前處理器 -> 前處理器定義,增加:

_CRT_SECURE_NO_DEPRECATE

方法三:方法二沒有使用更加安全的 CRT 函式,顯然不是一個值得推薦的好方法,但我們又不想一個一個地改函式名,這裡還有一個更簡便的方法:

在預編譯標頭檔案 stdafx.h 裡(同樣要在沒有include任何標頭檔案之前)定義下面的巨集:

#define_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

在連結的時候便會自動將舊函式替換成 Security CRT functions

注意:這個方法雖然使用了新的函式,但是不能消除警告(原因見紅字),你還得同時使用方法二(-_-)。即實際應在預編譯標頭檔案 stdafx.h 里加入下面兩句:

#define _CRT_SECURE_NO_DEPRECATE

#define_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1

錯誤原因解釋:

這種微軟的警告,主要因為那些C庫的函式,很多函式內部是不進行引數檢測的(包括越界類的),微軟擔心使用這些會造成記憶體異常,所以就改寫了同樣功能的函式,改寫了的函式進行了引數的檢測,使用這些新的函式會更安全和便捷。關於這些改寫的函式你不用專門去記憶,因為編譯器對於每個函式在給出警告時,都會告訴你相應的安全函式,檢視警告資訊就可以獲知,在使用時也再檢視一下MSDN詳細瞭解。

Linkerror: unresolved external symbol ConvertStringToBSTRConvertBSTRToString

解決方案:

新增comsupp.lib release 模式

comsuppw.lib  debug模式

#ifdef_DEBUG

#pragmacomment (lib, "comsuppwd.lib")

#else

#pragmacomment (lib, "comsuppw.lib")

#endif

參考資料

ADO第一次親密接觸 --ADO開發實踐之一

使用ADO實現BLOB資料的存取 -- ADO開發實踐之二

ProgrammaticallyInvoking the OLEDB Data Link Config Dialog

oledb資料來源連線配置對話方塊

自己如何正確獲取MYSQLADO連線字串