日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ADO

發(fā)布時間:2025/4/16 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ADO 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

1 基礎(chǔ)????1

1.1 引入ADO庫文件????1

1.1.1 版本????1

1.2 初始化OLE/COM庫環(huán)境????2

1.3 comdef.h????2

1.3.1 字符串編碼轉(zhuǎn)換????2

1.3.2 重要的類????3

1.3.3 重要的變量????4

1.3.4 智能指針????4

2 _ConnectionPtr????5

2.1 連接數(shù)據(jù)庫????5

2.2 執(zhí)行SQL語句????5

2.3 事務(wù)處理????6

2.4 斷開連接????7

3 _RecordsetPtr????8

3.1 打開記錄集????8

3.1.1 CursorLocation????9

3.1.2 CursorType????9

3.1.3 LockType????10

3.2 遍歷記錄集????11

3.3 關(guān)閉記錄集????12

3.4 訪問BLOB????12

3.4.1 寫入????12

3.4.2 讀取????14

3.4.3 更新????15

3.5 書簽????15

3.6 過濾????16

3.7 Find????16

3.8 Sort????17

3.9 Index????17

3.10 綁定數(shù)據(jù)????18

3.10.1 CADORecordBinding派生類????18

3.10.2 綁定????20

3.10.3 讀取字段????20

3.10.4 添加新記錄????21

4 _CommandPtr????23

4.1 執(zhí)行SQL語句????23

4.1.1 無名參數(shù)????23

4.1.2 有名參數(shù)????23

4.2 修改BLOB????24

4.3 執(zhí)行存儲過程????24

4.3.1 無名參數(shù)????25

4.3.2 有名參數(shù)????26

4.3.3 Refresh????27

4.3.4 游標位置????27

4.4 重復(fù)使用命令對象????28

5 ADOX????29

5.1 引入庫文件????29

5.1.1 一個BUG????29

5.2 創(chuàng)建數(shù)據(jù)庫????30

5.3 創(chuàng)建數(shù)據(jù)表????30

6 JRO????31

6.1 VB6.0????31

6.1.1 引用????31

6.1.2 代碼????31

6.2 VC++????32

6.2.1 引入????32

6.2.2 代碼????32

7 常見問題????33

7.1 連接失敗的原因????33

7.2 改變當前數(shù)據(jù)庫????33

7.3 判斷某個數(shù)據(jù)庫是否存在????33

7.4 判斷某個表是否存在????34

7.5 ADO鎖定整張表????34

7.6 獲取記錄集行數(shù)????35

7.7 解決并發(fā)沖突????35

?

?

1 基礎(chǔ)

1.1 引入ADO庫文件

VC++使用ADO,首先需要導(dǎo)入ADO的類型庫。可以在StdAfx.h里增加如下代碼:

#import "c:/program files/common files/system/ado/msado15.dll" no_namespace rename("EOF","adoEOF")

no_namespace表示不需要命名空間。刪除這個詞,則ADO的接口函數(shù)將被放在ADODB命名空間內(nèi)。也可以用rename_namespace("ADO")將命名空間更改為ADO

rename("EOF","adoEOF")表示將EOF更改為adoEOF。因為EOF在某些文件里被定義為(-1),如此一來,VARIANT_BOOL EOF;就變成了VARIANT_BOOL (-1);把它當做類成員變量編譯時就會出錯。

VC++編譯器中的預(yù)處理器針對這條指令做了哪些工作呢?

1、根據(jù)msado15.dll里的類型庫信息生成COM組件的接口文件。具體的就是生成msado15.tlhmsado15.tli,前者是聲明文件,后者是實現(xiàn)文件;

2、替換#import語句為#include "msado15.tlh"。這樣,源文件里就可以使用COM組件的接口了;

3msado15.tliCOM接口的實現(xiàn)文件,如果沒有它則程序可以編譯但無法連接。不過,msado15.tlimsado15.tlh包含起來了(通過#pragma start_map_region#include),且它的函數(shù)全部為內(nèi)聯(lián)的。因此,不用再單獨編譯msado15.tli

1.1.1 版本

Windows7 sp1里的msado15.dll,其類型庫版本為 6.1,而Windows XPmsado15.dll的版本為2.x。最關(guān)鍵的是新版本的類型庫并不是向下兼容的!

如果在Windows7下編譯代碼,然后在Windows XP下運行,就有可能會出現(xiàn)問題。解決方法有兩個:

1#import "msado15.dll"中的msado15.dll請使用低版本的,即Windows XP里的msado15.dll

2、升級Windows XP里的ADO組件。

1.2 初始化OLE/COM庫環(huán)境

ADO是一組COM動態(tài)庫,所以使用ADO前,必須初始化OLE/COM庫。在MFC應(yīng)用程序里,一個比較好的方法是在應(yīng)用程序主類的InitInstance成員函數(shù)里初始化OLE/COM庫。

BOOL CMyAdoTestApp::InitInstance()

{

AfxOleInit();????//這就是初始化COM

……

}

也可以使用 CoInitializeCoInitializeExOleInitialize初始化COM庫,退出程序前請使用CoUninitializeOleUninitialize

1.3 comdef.h

msado15.tlh文件里,語句#include <comdef.h>包含了comdef.h頭文件,這個頭文件里又有如下語句:

... ... ...

#include <comutil.h>

... ... ...

#pragma comment(lib, "comsupp.lib")

comdef.hcomutil.hcomsupp.lib包含了一些重要的變量、函數(shù)、類。

1.3.1 字符串編碼轉(zhuǎn)換

comutil.h頭文件里有兩個函數(shù)可用于字符串的編碼轉(zhuǎn)換:

namespace _com_util

{

BSTR __stdcall ConvertStringToBSTR(const char*pSrc);

char* __stdcall ConvertBSTRToString(BSTR pSrc);

}

_com_util::ConvertStringToBSTRAnsi字符串轉(zhuǎn)換為Unicode字符串,返回值記得要調(diào)用SysFreeString釋放內(nèi)存;

_com_util::ConvertBSTRToString Unicode字符串轉(zhuǎn)換為Ansi字符串,返回值記得要調(diào)用 delete[] 釋放內(nèi)存;

這兩個函數(shù)的實現(xiàn)代碼在comsupp.lib里。

1.3.2 重要的類

comutil.hcomdef.h這兩個頭文件里,有三個重要的類:_bstr_t_variant_t_com_error

_bstr_t 封裝了BSTR_variant_t封裝了VARIANT_com_error封裝了COM錯誤。

使用_bstr_t_variant_t可以極大的簡化代碼。以下面的代碼進行說明:

_RecordsetPtr m_pRecordset;

... ... ...

_variant_t vAge = m_pRecordset->GetCollect(_T("Age"));

上面的代碼用來讀取字段Age。查看msado15.tli里的Recordset15::GetCollect函數(shù),可以知道COM組件返回的其實是一個VARIANTGetCollect函數(shù)返回前創(chuàng)建了一個臨時_variant_t對象,將VARIANT封裝了起來并返回給vAge

vAge析構(gòu)時將調(diào)用VariantClear銷毀COM組件返回的VARIANT。如果Age字段是一個BSTR字符串,VariantClear會調(diào)用SysFreeString釋放BSTR字符串。

如果不借助_variant_t,而直接使用VARIANT,會是什么情況呢?那就是必須顯式的調(diào)用VariantClear函數(shù),銷毀COM組件返回的每一個VARIANT。這樣代碼就會顯得非常臃腫,而且一旦疏忽就會發(fā)生內(nèi)存泄露。

此外,使用_bstr_t也會相當?shù)姆奖恪?/span>

如:代碼_bstr_t s(m_pRecordset->GetCollect(_T("Age")));會自動將GetCollect返回的_variant_t轉(zhuǎn)換為BSTR字符串。

如:可以使用Ansi字符串構(gòu)造_bstr_t對象

_bstr_t s1("測試_bstr_t");

如:可以使用Unicode字符串構(gòu)造_bstr_t對象

_bstr_t s2(L"測試_bstr_t");

如:可以將Ansi字符串或Unicode字符串賦給_bstr_t變量

s1 = "_bstr_t測試";

s2 = L"_bstr_t測試";

如:可以輕松獲得Ansi字符串或Unicode字符串

const char*????????sA????=????(const char*)s1;????????????//返回Ansi字符串

const wchar_t*????sW????=????(const wchar_t*)s1;????????//返回Unicode字符串

需要注意的是:上面的sAsW所指向的內(nèi)存由_bstr_t維護。_bstr_t對象s1析構(gòu)時,sAsW也就成為了野指針。

1.3.3 重要的變量

comutil.h里,有全局變量vtMissing,其定義如下:

extern _variant_t vtMissing;

它其實是類型為VT_EMPTYVARIANT

1.3.4 智能指針

_COM_SMARTPTR_TYPEDEF用來聲明智能指針。

如:智能指針_ConnectionPtr的聲明如下:

_COM_SMARTPTR_TYPEDEF(_Connection, __uuidof(_Connection));

宏展開之后,其實就是:

typedef _com_ptr_t< _com_IIID<_Connection, &__uuidof(_Connection)> > _ConnectionPtr;

_ConnectionPtr的實質(zhì)就是一個自動維護COM計數(shù)的_Connection

?

2 _ConnectionPtr

_ConnectionPtr表示與數(shù)據(jù)庫的連接。

2.1 連接數(shù)據(jù)庫

下面的代碼將實例化一個_ConnectionPtr,并連接數(shù)據(jù)庫

HRESULT hr = S_OK;

_ConnectionPtr m_pConnection;

{//創(chuàng)建連接

try

{

//創(chuàng)建 COM 對象,__uuidof(Connection) 可以替換為 "ADODB.Connection"

hr = m_pConnection.CreateInstance(__uuidof(Connection));

if(SUCCEEDED(hr))

{//連接 Access 數(shù)據(jù)庫 Demo.mdb

m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb"

,"","",adModeUnknown);

}

}

catch(_com_error& e)

{

AfxMessageBox(e.Description());

}

}?

m_pConnection->Open用來連接數(shù)據(jù)庫。第一個參數(shù)用來指定連接字符串;第二、三個參數(shù)分別為用戶名和密碼;第四個參數(shù)是enum ConnectModeEnum,對數(shù)據(jù)庫的讀寫進行控制,如:adModeRead表示只讀……

2.2 執(zhí)行SQL語句

Execute方法將執(zhí)行SQL語句,其聲明如下:

_RecordsetPtr Connection15::Execute(_bstr_t CommandText

????????????????????????,VARIANT*RecordsAffected

????????????????????????,long Options);

CommandText????????是命令字串,通常是SQL命令

RecordsAffected????是操作完成后所影響的行數(shù)

Options????????????????表示CommandText的類型,取值如下

????????????????????adCmdText????????????表明CommandText是文本

????????????????????adCmdTable????????????表明CommandText是表名

????????????????????adCmdProc????????????表明CommandText是存儲過程

????????????????????adCmdUnknown????????未知

Execute執(zhí)行完后返回一個記錄集。

示例代碼如下:

_variant_t RecordsAffected;

//執(zhí)行SQL命令,創(chuàng)建表格

m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",&RecordsAffected,adCmdText);

//往表格里面添加記錄

m_pConnection->Execute("INSERT INTO users(ID,username,old,birthday) VALUES (1, ''''Washington'''',25,''''1970/1/1'''')",&RecordsAffected,adCmdText);

//將所有記錄old字段的值加一

m_pConnection->Execute("UPDATE users SET old = old + 1"

,&RecordsAffected,adCmdText);

//執(zhí)行SQL統(tǒng)計命令得到包含記錄條數(shù)的記錄集

m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM users"

,&RecordsAffected,adCmdText);

//取得第一個字段的值放入vCount變量

_variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));

m_pRecordset->Close();//關(guān)閉記錄集

CString message;

message.Format("共有%d條記錄",vCount.lVal);

AfxMessageBox(message);///顯示當前記錄條數(shù)

2.3 事務(wù)處理

ADO中的事務(wù)處理也很簡單,只需分別在適當?shù)奈恢谜{(diào)用Connection對象的三個方法即可,這三個方法是:

1、在事務(wù)開始時調(diào)用

pCnn->BeginTrans();

2、在事務(wù)結(jié)束并成功時調(diào)用

pCnn->CommitTrans();

3、在事務(wù)結(jié)束并失敗時調(diào)用

pCnn->RollbackTrans();

在使用事務(wù)處理時,應(yīng)盡量減小事務(wù)的范圍,即減小從事務(wù)開始到結(jié)束(提交或回滾)之間的時間間隔,以便提高系統(tǒng)效率。需要時也可在調(diào)用BeginTrans()方法之前,先設(shè)置Connection對象的IsolationLevel屬性值,詳細內(nèi)容參見MSDN中有關(guān)ADO的技術(shù)資料。

2.4 斷開連接

下面的代碼將斷開與數(shù)據(jù)庫的連接,并銷毀_ConnectionPtr實例

if(m_pConnection)

{//關(guān)閉ADO連接

if(m_pConnection->State)

{

m_pConnection->Close();

}

//下面的語句可有可無。因為m_pConnection是智能指針,析構(gòu)時會自動Release

m_pConnection.Release();

}

?

3 _RecordsetPtr

_RecordsetPtr表示記錄集。

3.1 打開記錄集

使用Open方法打開記錄集,其聲明如下:

HRESULT Recordset15::Open(const _variant_t& Source

????????????????????????????,const _variant_t & ActiveConnection

????????????????????????????,enum CursorTypeEnum CursorType

????????????????????????????,enum LockTypeEnum LockType

????????????????????????????,long Options);

Source????????????????數(shù)據(jù)查詢字符串

ActiveConnection????_Connection*或連接數(shù)據(jù)庫的字符串

CursorType????????????光標類型

LockType????????????鎖定類型

Options????????????????可以取如下值之一:

????????????????????adCmdText????????????表明CommandText是文本命令

????????????????????adCmdTable????????????表明CommandText是表名

????????????????????adCmdProc????????????表明CommandText是存儲過程

????????????????????adCmdUnknown????????未知

下面的代碼首先實例化一個_RecordsetPtr,然后在_ConnectionPtr的基礎(chǔ)上,打開一個記錄集。注意Open函數(shù)的第二個參數(shù),表示數(shù)據(jù)庫連接。

_RecordsetPtr m_pRecordset;

try

{

//創(chuàng)建 COM 對象,__uuidof(Recordset) 可以替換為 "ADODB.Recordset"

hr = m_pRecordset.CreateInstance(__uuidof(Recordset));

if(SUCCEEDED(hr))

{

m_pRecordset->CursorLocation = adUseClient;

m_pRecordset->Open(_T("SELECT * FROM DemoTable")

,m_pConnection.GetInterfacePtr()

,adOpenDynamic

,adLockOptimistic //樂觀鎖

,adCmdText);

}

}

catch(_com_error& e)

{

AfxMessageBox(e.Description());

}

可以將Open函數(shù)的第二個參數(shù)更換為連接字符串,如:"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Demo.mdb"。在此情況下,Open函數(shù)首先連接數(shù)據(jù)庫,然后再打開一個記錄集。

3.1.1 CursorLocation

CursorLocation表示游標的位置,有兩個選項:

adUseServer????=????2????//默認,表示游標在服務(wù)端

adUseClient????????=????3????//表示游標在客戶端

游標在服務(wù)端,則記錄集對數(shù)據(jù)變化是敏感的。亦即當其它用戶修改了數(shù)據(jù)庫內(nèi)的數(shù)據(jù)后,有可能會影響到客戶端已經(jīng)打開的記錄集。游標在客戶端,就不會有數(shù)據(jù)敏感性了。

游標在服務(wù)端,則客戶端打開記錄集時數(shù)據(jù)將保留在服務(wù)端,不會通過網(wǎng)絡(luò)傳給客戶端。但是訪問記錄集里的數(shù)據(jù)時,就會頻繁的網(wǎng)絡(luò)通訊。游標在客戶端,則客戶端打開記錄集時數(shù)據(jù)將通過網(wǎng)絡(luò)緩存到客戶端。訪問記錄集里的數(shù)據(jù)時,將不再需要網(wǎng)絡(luò)通訊。因此,如果頻繁的訪問數(shù)據(jù)則客戶端游標的性能較高。

此外,服務(wù)端游標不支持書簽而客戶端游標支持書簽。這將影響到某些函數(shù)的使用,如:GetRecordCount函數(shù)有可能返回-1,而不是實際的記錄個數(shù)。

3.1.2 CursorType

游標類型有四種:

adOpenForwardOnly????????=????0,????//向前游標

adOpenKeyset????????????=????1,????//鍵集游標

adOpenDynamic????????=????2,????//動態(tài)游標

adOpenStatic????????????=????3????//靜態(tài)游標

adOpenForwardOnlyadOpenStatic 表示記錄集是靜態(tài)的:打開記錄集后,它就不會再發(fā)生變化,即使其他用戶修改了數(shù)據(jù)庫里的數(shù)據(jù)。兩者的區(qū)別在于adOpenForwardOnly只能向前移動游標,而adOpenStatic可以任意移動游標。

adOpenKeysetadOpenDynamic 表示記錄集是動態(tài)的:打開記錄集后,能夠反映其他用戶所做的修改。

adOpenKeyset 的實現(xiàn)原理:打開的記錄集僅僅保存記錄的關(guān)鍵字(Key),訪問某條記錄時是根據(jù) Key 到數(shù)據(jù)庫訪問的。所以,其他用戶修改了某條記錄后,再訪問這條記錄,是能夠發(fā)現(xiàn)記錄改變了。但是,其他用戶如果增加、刪除記錄,并不會更改關(guān)鍵字記錄集,因此通過關(guān)鍵字記錄集,無法及時獲知增加、刪除的記錄。

adOpenDynamic 的實現(xiàn)原理:打開的記錄集會根據(jù)數(shù)據(jù)庫內(nèi)容的變化及時予以更新。但是需要注意CursorLocation 必須等于 adUseServer,即游標必須在服務(wù)端才能實現(xiàn)此功能。

3.1.3 LockType

adLockReadOnly????????=????1,????????//只讀

adLockPessimistic????????=????2, ????????//悲觀鎖

adLockOptimistic????????=????3, ????????//樂觀鎖

adLockBatchOptimistic????=????4 ????????//批量樂觀鎖

悲觀鎖要求CursorLocation = adUseServer。它表示:編輯字段時就鎖定記錄,Update之后停止鎖定。這種方法最保險,但是效率最低;

樂觀鎖只有在 Update 時才鎖定記錄,更新完畢后停止鎖定。也就是說,每調(diào)用一次Update,都會鎖定、解鎖一次;

批量樂觀鎖表示調(diào)用UpdateBatch時鎖定記錄,批量更新完畢后停止鎖定。也就是說,每調(diào)用一次UpdateBatch,都會鎖定、解鎖一次。

假定使用悲觀鎖,多用戶執(zhí)行下面三行代碼,會發(fā)生什么情況呢?

m_pRecordset->MoveFirst();

m_pRecordset->PutCollect("name","Test");

m_pRecordset->Update();

用戶A執(zhí)行到m_pRecordset->PutCollect,將鎖定記錄集的第一行。其它用戶運行到m_pRecordset->PutCollect時,也想鎖定第一行,但因為已經(jīng)被A鎖定,所以其它用戶執(zhí)行到此行時會等待若干時間后拋出異常。

用戶A執(zhí)行完m_pRecordset->Update后,將解鎖記錄集的第一行。注意:具體何時解鎖,每種數(shù)據(jù)庫好像不盡相同。經(jīng)筆者測試,發(fā)現(xiàn)Access2000Update后即解鎖,而SQL Server2008在記錄集關(guān)閉后才解鎖。

3.2 遍歷記錄集

如下代碼將遍歷記錄集。

_variant_t var;

CString sName,sAge;

try

{

//如果 BOF EOF 均為真,則無記錄

if(!m_pRecordset->BOF || !m_pRecordset->adoEOF)

{

m_pRecordset->MoveFirst();

while(!m_pRecordset->adoEOF)

{

var = m_pRecordset->GetCollect(_T("Name"));

if(var.vt != VT_NULL)

{//姓名

sName = (LPCTSTR)_bstr_t(var);

}

else

{

sName.Empty();

}

var = m_pRecordset->GetCollect(_T("Age"));

if(var.vt != VT_NULL)

{//年齡

sAge = (LPCTSTR)_bstr_t(var);

}

else

{

sAge.Empty();

}

m_pRecordset->MoveNext();

}

}

}

catch(_com_error& e)

{

AfxMessageBox(e.Description());

}

var = m_pRecordset->GetCollect(_T("Name"));的等價代碼如下:

FieldsPtr????pFields????=????m_pRecordset->Fields;

FieldPtr????????pField????=????pFields->Item[_T("Name")];

var????????????????????=????pField->Value;

3.3 關(guān)閉記錄集

下面的代碼將關(guān)閉記錄集,并銷毀_RecordsetPtr實例。

if(m_pRecordset)

{//關(guān)閉記錄集

if(m_pRecordset->State)

{

m_pRecordset->Close();

}

//下面的語句可有可無。因為m_pRecordset是智能指針,析構(gòu)時會自動Release

m_pRecordset.Release();

}

3.4 訪問BLOB

Microsoft SQL中,textimage……被當做二進制數(shù)據(jù)進行處理。

可以用Field對象的GetChunkAppendChunk方法來訪問。每次可以讀出或?qū)懭肴繑?shù)據(jù)的一部分,它會記住上次訪問的位置。但是如果中間訪問了別的字段后,就又得從頭來了。

3.4.1 寫入

可以使用m_pRecordset->PutCollect("data",varBLOB)將二進制數(shù)據(jù)一次性寫入,也可以使用AppendChunk分多次寫入二進制數(shù)據(jù)。

void CDlgMain::blobFileToDB(LPCTSTR szFile)

{

CFile f;

if(f.Open(szFile,CFile::modeRead | CFile::shareDenyWrite))

{

FieldPtr fd = m_pRecordset->Fields->Item["data"];

DWORD dwSize = f.GetLength();

if(dwSize > 0)

{

const int????????????nBlock????????= 1024;

DWORD????dwWrite????????= 0; //已經(jīng)寫入數(shù)據(jù)庫的字節(jié)數(shù)

DWORD????????????dwAppend????= 0; //單次寫入的字節(jié)數(shù)

UINT????????????????uRead????????= 0;

SAFEARRAY*????psa????????= SafeArrayCreateVector(VT_UI1,0,nBlock);

_variant_t????????????vBLOB;

vBLOB.vt????????????=????VT_ARRAY | VT_UI1;

vBLOB.parray????????=????psa;

?

for(;;)

{

dwAppend = dwSize - dwWrite;

if(!dwAppend)

{

break;

}

if(dwAppend > nBlock)

{

dwAppend = nBlock;

}

SafeArrayLock(psa);

uRead = f.Read(psa->pvData,dwAppend);

SafeArrayUnlock(psa);

if(uRead != dwAppend)

{

break;

}

psa->rgsabound[0].cElements = dwAppend;

fd->AppendChunk(vBLOB);

dwWrite += dwAppend;

}

//SafeArrayDestroy(psa); //vBLOB析構(gòu)時會自動釋放數(shù)組 psa

}

else

{

_variant_t vNull;

vNull.vt = VT_NULL;

fd->PutValue(vNull);

}

f.Close();

}

}

代碼fd->PutValue(vNull);相當于m_pRecordset->PutCollect("data",vNull)用來設(shè)置BLOBNULL,也就是清空。也可以使用SQL語句清空某個BLOB字段,如:

UPDATE 表名 SET BLOB字段名 = NULL WHERE ID=1

3.4.2 讀取

可以使用m_pRecordset-> GetCollect("data")將二進制數(shù)據(jù)一次性讀取出來,也可以使用GetChunk分多次讀取二進制數(shù)據(jù)。

void CDlgMain::blobDBtoFile(LPCTSTR szFile)

{

CFile f;

if(f.Open(szFile,CFile::modeWrite | CFile::modeCreate))

{

FieldPtr????fd????????????=????m_pRecordset->Fields->Item["data"];

long????????nSizeActual????=????fd->ActualSize;

if(nSizeActual > 0)

{

const int????????????nBlock????=????1024;

long????????????????nRead????=????0; ????//已經(jīng)讀取的字節(jié)數(shù)

long????????????????nGet????=????0; ????//單次讀取的字節(jié)數(shù)

_variant_t????????????vBLOB;

ULONG????????????uWrite????=????0; ????//單次寫入文件的字節(jié)數(shù)

SAFEARRAY*????psa;

?

for(;;)

{

nGet = nSizeActual - nRead;

if(!nGet)

{

break;

}

if(nGet > nBlock)

{

nGet = nBlock;

}

vBLOB = fd->GetChunk(nGet);

nRead += nGet;

if(vBLOB.vt == (VT_ARRAY | VT_UI1)

&& (psa = vBLOB.parray) && psa->cDims == 1)

{

uWrite = psa->rgsabound[0].cElements;

if(uWrite)

{

SafeArrayLock(psa);

f.Write(psa->pvData,uWrite);

SafeArrayUnlock(psa);

}

}

}

}

f.Close();

}

}

3.4.3 更新

通過_CommandPtr,執(zhí)行帶參數(shù)的SQL語句,可實現(xiàn)BLOB數(shù)據(jù)的修改。請參考_CommandPtr這一章。

3.5 書簽

書簽(bookmark)可以唯一標識記錄集中的一個記錄,用于快速地將當前記錄移回到已訪問過的記錄,以及進行過濾等等。Provider會自動為記錄集中的每一條記錄產(chǎn)生一個書簽,我們只需要使用它就行了。我們不能試圖顯示、修改或比較書簽。ADO用記錄集的Bookmark屬性表示當前記錄的書簽。

用法步驟:

rst->Supports(adBookmark);????????????//判斷是否支持書簽

_variant_t VarBookmark;????????????//建立書簽變量

VarBookmark = rst->Bookmark;????????//獲得書簽值

... ... ...????????????????????????//可以移動記錄

if(VarBookmark.vt != VT_EMPTY)

{//將記錄位置恢復(fù)到書簽位置

rst->Bookmark = VarBookmark;

}

3.6 過濾

Recordset對象的Filter屬性表示了當前的過濾條件。它的值可以是以ANDOR連接起來的條件表達式(不含WHERE關(guān)鍵字)、由書簽組成的數(shù)組或ADO提供的FilterGroupEnum枚舉值。為Filter屬性設(shè)置新值后Recordset的當前記錄指針會自動移動到滿足過濾條件的第一個記錄。例如:

rst->Filter = _bstr_t ("姓名='趙薇' AND 性別='女'");

在使用條件表達式時應(yīng)注意下列問題:

1、可以用圓括號組成復(fù)雜的表達式

例如:

rst->Filter = _bstr_t ("(姓名='趙薇' AND 性別='女') OR AGE<25");

但是微軟不允許在括號內(nèi)用OR,然后在括號外用AND,例如:

rst->Filter = _bstr_t ("(姓名='趙薇' OR 性別='女') AND AGE<25");

必須修改為:

rst->Filter = _bstr_t ("(姓名='趙薇' AND AGE<25) OR (性別='女' AND AGE<25)");

2、表達式中的比較運算符可以是LIKE

LIKE后被比較的是一個含有通配符*的字符串,星號表示若干個任意的字符。

字符串的首部和尾部可以同時帶星號*

rst->Filter = _bstr_t ("姓名 LIKE '**' ");

也可以只是尾部帶星號:

rst->Filter = _bstr_t ("姓名 LIKE '*' ");

Filter屬性值的類型是Variant,如果過濾條件是由書簽組成的數(shù)組,則需將該數(shù)組轉(zhuǎn)換為SafeArray,然后再封裝到一個VARIANT_variant_t型的變量中,再賦給Filter屬性。

3.7 Find

以下代碼用于查找記錄

pRst->Find("姓名 = '趙薇'",1,adSearchForward);

一般情況下,這種查找是順序查找,效率較低。可針對某個字段進行排序,其方法如下:

//將該字段的Optimize屬性設(shè)置為True

pRst->Fields->GetItem("姓名")->Properties->

GetItem("Optimize")->PutValue("True");

... ... ...

pRst->Find("姓名 = '趙薇'",1,adSearchForward);

... ... ...

//將該字段的Optimize屬性設(shè)置為False

pRst->Fields->GetItem("姓名")->Properties->

GetItem("Optimize")->PutValue("False");

3.8 Sort

要排序也很簡單,只要把要排序的關(guān)鍵字列表設(shè)置到Recordset對象的Sort屬性里即可,例如:

pRstAuthors->CursorLocation = adUseClient;

pRstAuthors->Open("SELECT * FROM mytable"

????????????????????,_variant_t((IDispatch *)pConnection)

????????????????????,adOpenStatic,adLockReadOnly, adCmdText);

......

pRst->Sort = "姓名 DESC, 年齡 ASC";

關(guān)鍵字(即字段名)之間用逗號隔開,如果要以某關(guān)鍵字降序排序,則應(yīng)在該關(guān)鍵字后加一空格,再加DESC(如上例)。升序時ASC加不加無所謂。本操作是利用索引進行的,并未進行物理排序,所以效率較高。

但要注意,在打開記錄集之前必須將記錄集的CursorLocation屬性設(shè)置為adUseClient,如上例所示。Sort屬性值在需要時隨時可以修改。

3.9 Index

pRst->Index="";????????????//首先設(shè)置索引(數(shù)據(jù)庫里建立的索引)

pRst->Seek(...,...);????????//有序查找

3.10 綁定數(shù)據(jù)

定義一個綁定類,將其成員變量綁定到一個指定的記錄集,以方便于訪問記錄集的字段值。

3.10.1 CADORecordBinding派生類

class CCustomRs : public CADORecordBinding

{

BEGIN_ADO_BINDING(CCustomRs)

ADO_VARIABLE_LENGTH_ENTRY2(3

????????????????????????????????????????????,adVarChar

????????????????????????????????????????????,m_szau_fname

????????????????????????????????????????????,sizeof(m_szau_fname)

????????????????????????????????????????????,lau_fnameStatus

????????????????????????????????????????????,false)

ADO_VARIABLE_LENGTH_ENTRY2(2

????????????????????????????????????????????,adVarChar

????????????????????????????????????????????,m_szau_lname

????????????????????????????????????????????,sizeof(m_szau_lname)

????????????????????????????????????????????,lau_lnameStatus

????????????????????????????????????????????,false)

ADO_VARIABLE_LENGTH_ENTRY2(4

????????????????????????????????????????????,adVarChar

????????????????????????????????????????????,m_szphone

????????????????????????????????????????????,sizeof(m_szphone)

????????????????????????????????????????????,lphoneStatus

????????????????????????????????????????????,true)

END_ADO_BINDING()

public:

CHAR m_szau_fname[22];

ULONG lau_fnameStatus;

CHAR m_szau_lname[42];

ULONG lau_lnameStatus;

CHAR m_szphone[14];

ULONG lphoneStatus;

};

其中將要綁定的字段與變量名用BEGIN_ADO_BINDING宏關(guān)聯(lián)起來。每個字段對應(yīng)于兩個變量,一個存放字段的值,另一個存放字段的狀態(tài)。字段用從1開始的序號表示,如123等等。

特別要注意的是:如果要綁定的字段是字符串類型,則對應(yīng)的字符數(shù)組的元素個數(shù)一定要比字段長度大2(比如m_szau_fname[22],其綁定的字段au_fname的長度實際是20),不這樣綁定就會失敗。我分析多出的2可能是為了存放字符串結(jié)尾的空字符nullBSTR字符串開頭的一個字(表示BSTR的長度)。這個問題對于初學(xué)者來說可能是一個意想不到的問題。

CADORecordBinding類的定義在icrsint.h文件里,內(nèi)容是:

class CADORecordBinding

{

public:

STDMETHOD_(const ADO_BINDING_ENTRY*, GetADOBindingEntries) (VOID) PURE;

};

BEGIN_ADO_BINDING宏的定義也在icrsint.h文件里,內(nèi)容是:

#define BEGIN_ADO_BINDING(cls) public: /

typedef cls ADORowClass; /

const ADO_BINDING_ENTRY* STDMETHODCALLTYPE GetADOBindingEntries() { /

static const ADO_BINDING_ENTRY rgADOBindingEntries[] = {

ADO_VARIABLE_LENGTH_ENTRY2宏的定義也在icrsint.h文件里:

#define ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)/

{Ordinal, /

DataType, /

0, /

0, /

Size, /

offsetof(ADORowClass, Buffer), /

offsetof(ADORowClass, Status), /

0, /

classoffset(CADORecordBinding, ADORowClass), /

Modify},

#define END_ADO_BINDING宏的定義也在icrsint.h文件里:

#define END_ADO_BINDING() {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};/

return rgADOBindingEntries;}

3.10.2 綁定

_RecordsetPtr Rs1;

IADORecordBinding *picRs=NULL;

CCustomRs rs;

......

Rs1->QueryInterface(__uuidof(IADORecordBinding),(LPVOID*) picRs);

picRs->BindToRecordset(&rs);

派生出的類必須通過IADORecordBinding接口才能綁定,調(diào)用它的BindToRecordset方法就行了。

3.10.3 讀取字段

rs中的變量即是當前記錄字段的值

//Set sort and filter condition:

// Step 4: Manipulate the data

Rs1->Fields->GetItem("au_lname")->Properties->

GetItem("Optimize")->Value = true;

Rs1->Sort = "au_lname ASC";

Rs1->Filter = "phone LIKE '415 5*'";

Rs1->MoveFirst();

while (VARIANT_FALSE == Rs1->EndOfFile)

{

printf("Name: %s/t %s/tPhone: %s/n"

,(rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : "")

,(rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : "")

,(rs.lphoneStatus == adFldOK ? rs.m_szphone : ""));

if (rs.lphoneStatus == adFldOK)

strcpy(rs.m_szphone, "777");

TESTHR(picRs->Update( // Add change to the batch

Rs1->MoveNext();

}

Rs1->Filter = (long) adFilterNone;

......

if (picRs)

{

picRs->Release();

}

Rs1->Close();

pConn->Close();

只要字段的狀態(tài)是adFldOK,就可以訪問。如果修改了字段,不要忘了先調(diào)用picRsUpdate(注意不是RecordsetUpdate),然后才關(guān)閉,也不要忘了釋放picRs(即picRs->Release();)。

3.10.4 添加新記錄

此時還可以用IADORecordBinding接口添加新記錄

if(FAILED(picRs->AddNew(&rs)))

......

?

4 _CommandPtr

_CommandPtr用來執(zhí)行SQL語句或調(diào)用存儲過程。

4.1 執(zhí)行SQL語句

下面的代碼首先實例化一個_CommandPtr,然后執(zhí)行一條SQL語句,執(zhí)行返回的結(jié)果就是一個記錄集:

_CommandPtr cmd;

cmd.CreateInstance(__uuidof(Command));

cmd->ActiveConnection????=????theApp.m_pConnection;

cmd->CommandText????????=????"select * from file where name like '%.jpg'";

_RecordsetPtr????rs????????=????cmd->Execute(NULL,NULL,adCmdText);

_CommandPtr不僅僅能執(zhí)行SQL語句,它還可以給SQL語句傳遞參數(shù)。

4.1.1 無名參數(shù)

下面的代碼中,SQL語句中的?號就是一個無名參數(shù)。執(zhí)行SQL語句時,從左至右第一個?號將被cmd->Parameters->Item[0]->Value代替;第二個?號將被cmd->Parameters->Item[1]->Value代替……

所以,調(diào)用cmd->Execute執(zhí)行SQL語句前,需要調(diào)用cmd->CreateParameter創(chuàng)建參數(shù),并調(diào)用cmd->Parameters->Append將此參數(shù)添加至cmd->Parameters集合。

_CommandPtr cmd;

cmd.CreateInstance(__uuidof(Command));

cmd->ActiveConnection????=????theApp.m_pConnection;

cmd->CommandText????????=????"select * from file where name like ?";

cmd->Parameters->Append(

????????????????cmd->CreateParameter("",adChar,adParamInput,-1,"%.jpg"));

_RecordsetPtr????rs????????=????cmd->Execute(NULL,NULL,adCmdText);

4.1.2 有名參數(shù)

下面的代碼中,SQL語句中的@name就是一個有名參數(shù)。執(zhí)行SQL語句時,@name將被cmd->Parameters->Item["@name"]->Value代替。

所以,調(diào)用cmd->Execute執(zhí)行SQL語句前,需要調(diào)用cmd->CreateParameter創(chuàng)建有名參數(shù),并調(diào)用cmd->Parameters->Append將此參數(shù)添加至cmd->Parameters集合。

_CommandPtr cmd;

cmd.CreateInstance(__uuidof(Command));

cmd->ActiveConnection????=????theApp.m_pConnection;

cmd->CommandText????????=????"select * from file where name like @name";

cmd->Parameters->Append(

????????????????cmd->CreateParameter("@name",adChar,adParamInput,-1,"%.jpg"));

_RecordsetPtr????rs????????=????cmd->Execute(NULL,NULL,adCmdText);

4.2 修改BLOB

通過_CommandPtr,執(zhí)行帶參數(shù)的SQL語句,可實現(xiàn)BLOB數(shù)據(jù)的修改。

_variant_t vBLOB;

vBLOB.vt = VT_ARRAY | VT_UI1;

vBLOB.parray = SafeArrayCreateVector(VT_UI1,0,30);

SafeArrayLock(vBLOB.parray);

memset(vBLOB.parray->pvData,0,30);

SafeArrayUnlock(vBLOB.parray);

?

_CommandPtr cmd(__uuidof(Command));

cmd->ActiveConnection = theApp.m_pConnection;

cmd->CommandText = "UPDATE 表名 SET BLOB字段名=? WHERE ID='1'";

cmd->Parameters->Append(

cmd->CreateParameter("",adVarBinary,adParamInput,-1,vBLOB));

cmd->Execute(NULL,NULL,adCmdText);

4.3 執(zhí)行存儲過程

SQL2008里,執(zhí)行如下SQL語句,創(chuàng)建一個存儲過程:

if exists (select * from sysobjects where id = object_id(N'[sp_1]') and OBJECTPROPERTY(id, N'IsProcedure')= 1)

drop procedure sp_1

GO

?

CREATE PROCEDURE sp_1(@pin1 int

,@pin2 CHAR(10)

,@pout1 int OUTPUT

,@pout2 CHAR(10) OUTPUT)

AS

BEGIN

declare @retval int

select @pout1 = @pin1 + 100

select @pout2 = left( ltrim(rtrim(@pin2)) + '123' , 10)

select * from [file]

select @retval = 1236

return @retval

END

GO

?

exec sp_1 10,'Test',20,'789'

GO

使用_CommandPtr執(zhí)行這個存儲過程,需要傳遞、接收的參數(shù)如下:

@RETURN_VALUE(int,返回值)????????????//0個參數(shù),返回值

@pin1(int,輸入)????????????????????????????//1個參數(shù)

@pin2(char(10),輸入)????????????????????//2個參數(shù)

@pout1(int ,輸入/輸出)????????????????????//3個參數(shù)

@pout2(char(10),輸入/輸出)????????????????//4個參數(shù)

4.3.1 無名參數(shù)

不使用Refresh方法,執(zhí)行存儲過程的代碼如下:

_CommandPtr cmd;

cmd.CreateInstance(__uuidof(Command));

cmd->ActiveConnection????=????theApp.m_pConnection;

cmd->CommandText????????=????"sp_1"; //存儲過程名稱

//添加參數(shù)——返回值

cmd->Parameters->Append(

????????????cmd->CreateParameter("",adInteger,adParamReturnValue,sizeof(int)));

//添加參數(shù)——@pin1

cmd->Parameters->Append(

????????????cmd->CreateParameter("",adInteger,adParamInput,sizeof(int),3L));

//添加參數(shù)——@pin2

cmd->Parameters->Append(

????????????cmd->CreateParameter("",adChar,adParamInput,10,_variant_t(_T("DD1"))));

//添加參數(shù)——@pout1

cmd->Parameters->Append(

????????????cmd->CreateParameter("",adInteger,adParamOutput,sizeof(int)));

//添加參數(shù)——@pout2

cmd->Parameters->Append(

????????????cmd->CreateParameter("",adChar,adParamOutput,10));

//執(zhí)行存儲過程

theApp.m_pConnection->CursorLocation = adUseClient;

_RecordsetPtr????rs????=????cmd->Execute(NULL,NULL,adCmdStoredProc);

//獲取執(zhí)行結(jié)果

_variant_t vRet????????=????cmd->Parameters->Item[0L]->Value; //獲得返回值

_variant_t vin1????????=????cmd->Parameters->Item[1L]->Value; //獲得@pin1

_variant_t vin2????????=????cmd->Parameters->Item[2L]->Value; //獲得@pin2

_variant_t vout1????=????cmd->Parameters->Item[3L]->Value; //獲得@pout1

_variant_t vout2????=????cmd->Parameters->Item[4L]->Value; //獲得@pout2

總結(jié):不使用Refresh方法,則調(diào)用pCmd->Parameters->Append增加參數(shù)時,必須要注意參數(shù)的順序。

4.3.2 有名參數(shù)

如果創(chuàng)建參數(shù)時指定參數(shù)名稱,就可以根據(jù)名稱獲取執(zhí)行結(jié)果了。

//添加參數(shù)——返回值

cmd->Parameters->Append(

????cmd->CreateParameter("@RETURN_VALUE",adInteger,adParamReturnValue,sizeof(int)));

//添加參數(shù)——@pin1

cmd->Parameters->Append(

????cmd->CreateParameter("@pin1",adInteger,adParamInput,sizeof(int),3L));

//添加參數(shù)——@pin2

cmd->Parameters->Append(

????cmd->CreateParameter("@pin2",adChar,adParamInput,10,_variant_t(_T("DD1"))));

//添加參數(shù)——@pout1

cmd->Parameters->Append(

????cmd->CreateParameter("@pout1",adInteger,adParamOutput,sizeof(int)));

//添加參數(shù)——@pout2

cmd->Parameters->Append(

????cmd->CreateParameter("@pout2",adChar,adParamOutput,10));

//執(zhí)行存儲過程

theApp.m_pConnection->CursorLocation = adUseClient;

_RecordsetPtr????rs????=????cmd->Execute(NULL,NULL,adCmdStoredProc);

//獲取執(zhí)行結(jié)果

_variant_t vRet????????=????cmd->Parameters->Item["@RETURN_VALUE"]->Value;

_variant_t vin1????????=????cmd->Parameters->Item["@pin1"]->Value;

_variant_t vin2????????=????cmd->Parameters->Item["@pin2"]->Value;

_variant_t vout1????=????cmd->Parameters->Item["@pout1"]->Value;

_variant_t vout2????=????cmd->Parameters->Item["@pout2"]->Value;

注意:即便參數(shù)有了名稱,添加參數(shù)時的順序也不能改動。

4.3.3 Refresh

執(zhí)行cmd->Parameters->Refresh();會做哪些工作呢?

1、設(shè)置cmd->Parameters->Item[0L]

設(shè)置cmd->Parameters->Item[0L]->Name "@RETURN_VALUE"

設(shè)置cmd->Parameters->Item[0L]->Value VT_EMPTY

2、設(shè)置adParamInput參數(shù)的Value VT_EMPTY

3、設(shè)置adParamOutput參數(shù)的Value VT_NULL

當?shù)?/span>23、……次執(zhí)行cmd->Execute前,可以這么做:

cmd->Parameters->Refresh();

cmd->Parameters->Item["@pin1"]->Value????=????3L;

cmd->Parameters->Item["@pin2"]->Value????=????"C";

cmd->Execute(NULL,NULL,adCmdStoredProc);????????//2次執(zhí)行存儲過程

cmd->Parameters->Refresh();

cmd->Parameters->Item["@pin1"]->Value????=????4L;

cmd->Parameters->Item["@pin2"]->Value????=????"D";

cmd->Execute(NULL,NULL,adCmdStoredProc); ????????//3次執(zhí)行存儲過程

4.3.4 游標位置

如果游標位置不為adUseClient,那么取returnoutput參數(shù)之前,必須把返回的記錄集關(guān)閉掉。

下面的代碼能夠正常工作。因為這行代碼執(zhí)行完畢后,返回的記錄集會被銷毀,銷毀前會關(guān)閉記錄集。

pCmd->Execute(NULL,NULL,adCmdStoredProc);

下面的代碼就得注意了。在 rs 銷毀前,能否取得returnoutput參數(shù),取決于游標位置是否為adUseClient。如果是adUseClient就能正常取值,否則必須關(guān)閉rs記錄集后,才能正常取值。

_RecordsetPtr rs = pCmd->Execute(NULL,NULL,adCmdStoredProc);

theApp.m_pConnection->CursorLocation的取值會影響到pCmd->Execute返回記錄集的游標位置。如:pCmd->Execute執(zhí)行前,執(zhí)行theApp.m_pConnection->CursorLocation = adUseClient,則返回記錄集的游標位置也是adUseClient

4.4 重復(fù)使用命令對象

一個命令對象如果要重復(fù)使用多次(尤其是帶參數(shù)的命令),則在第一次執(zhí)行之前,應(yīng)將它的Prepared屬性設(shè)置為TRUE。這樣會使第一次執(zhí)行減慢,但卻可以使以后的執(zhí)行全部加快。

?

?

5 ADOX

5.1 引入庫文件

#import "C:/program Files/Common Files/system/ado/msadox.dll"

5.1.1 一個BUG

打開文件msadox.tlh,可以看到以下內(nèi)容。其中,enum DataTypeEnum是先使用,后聲明的。

struct __declspec(uuid("0000061d-0000-0010-8000-00aa006d2ea4"))

Columns : _Collection

{

... ... ...

HRESULT Append (

const _variant_t & Item,

enum DataTypeEnum Type,

long DefinedSize );

... ... ...

};

?

enum DataTypeEnum

{

adEmpty = 0,

adTinyInt = 16,

... ... ...

};

在此情況下,如下代碼將會出現(xiàn)編譯錯誤。

#import "C:/Program Files/Common Files/System/ado/msado15.dll"\

rename("EOF","adoEOF") no_namespace

#import "C:/program Files/Common Files/system/ado/msadox.dll"

原因在于:編譯msadox.tlhColumns::Append函數(shù)的第2個參數(shù)將是msado15.tlh里的enum DataTypeEnum;編譯msadox.tliColumns::Append函數(shù)的第2個參數(shù)卻變成了msadox.tlh里的JRO::DataTypeEnum

解決方法一:調(diào)整import的順序

#import "C:/program Files/Common Files/system/ado/msadox.dll"

#import "C:/Program Files/Common Files/System/ado/msado15.dll"\

rename("EOF","adoEOF") no_namespace

解決方法二:都使用命名空間

#import "C:/Program Files/Common Files/System/ado/msado15.dll"\

rename("EOF","adoEOF")

#import "C:/program Files/Common Files/system/ado/msadox.dll"

5.2 創(chuàng)建數(shù)據(jù)庫

ADOX::_CatalogPtr pCatalog(__uuidof(ADOX::Catalog));

_bstr_t s("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=G:\\1.mdb");

pCatalog->Create(s);

5.3 創(chuàng)建數(shù)據(jù)表

ADODB::_ConnectionPtr conn(__uuidof(ADODB::Connection));

conn->Open(sConn,"","",ADODB::adModeUnknown);

conn->Execute("CREATE TABLE TestTable(記錄編號 INTEGER,姓名 TEXT,年齡 INTEGER)",NULL,ADODB::adCmdText);????

conn->Close();

?

6 JRO

JROJet and Replication Objects的縮寫,它可以用來壓縮Access數(shù)據(jù)庫文件。

6.1 VB6.0

6.1.1 引用

6.1.2 代碼

Dim sSrc As String

Dim sDes As String

sSrc = "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Engine Type=5;Data Source=G:\dbFile.mdb"

sDes = "Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Engine Type=5;Data Source=G:\1.mdb"

Dim oJetEngine As New JRO.JetEngine

oJetEngine.CompactDatabase sSrc, sDes

Set oJetEngine = Nothing

注意:"Jet OLEDB:Database Password="可以指定密碼。

6.2 VC++

6.2.1 引入

引入JRO需要引入ADO庫,代碼如下:

#import "C:/Program Files/Common Files/System/ado/msado15.dll"\

rename("EOF","adoEOF") no_namespace

#import "C:/Program Files (x86)/Common Files/System/ado/msjro.dll"

上面的ADO庫未使用命名空間,如果使用了命名空間,則代碼如下。增加了兩條using語句,否則無法完成編譯。

#import "C:/Program Files/Common Files/System/ado/msado15.dll"\

rename("EOF","adoEOF")

using ADODB::_Recordset;

using ADODB::_RecordsetPtr;

#import "C:/Program Files (x86)/Common Files/System/ado/msjro.dll"

6.2.2 代碼

AfxOleInit();

_bstr_t sSrc(_T("Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Engine Type=5;Data Source=G:\\dbFile.mdb"));

_bstr_t sDes(_T("Provider=Microsoft.Jet.OLEDB.4.0;Jet OLEDB:Engine Type=5;Data Source=G:\\1.mdb"));

JRO::IJetEnginePtr jet(__uuidof(JRO::JetEngine));

jet->CompactDatabase(sSrc,sDes);

注意:"Jet OLEDB:Database Password="可以指定密碼。

?

?

7 常見問題

7.1 連接失敗的原因

Enterprise Managemer內(nèi),打開將服務(wù)器的屬性對話框,在Security選項卡中,有一個選項Authentication

如果該選項是Windows NT only,則你的程序所用的連接字符串就一定要包含Trusted_Connection參數(shù),并且其值必須為yes,如:

"Provider=SQLOLEDB;Server=888;Trusted_Connection=yes"

";Database=master;uid=lad;";

如果不按上述操作,程序運行時連接必然失敗。

如果Authentication選項是SQL Server and Windows NT,則你的程序所用的連接字符串可以不包含Trusted_Connection參數(shù),如:

"Provider=SQLOLEDB;Server=888;Database=master;uid=lad;pwd=111;";

因為ADO給該參數(shù)取的默認值就是no,所以可以省略。我認為還是取默認值比較安全一些。

7.2 改變當前數(shù)據(jù)庫

使用Tansct-SQL中的USE語句即可。

7.3 判斷某個數(shù)據(jù)庫是否存在

1、可打開master數(shù)據(jù)庫中一個叫做SCHEMATA的視圖,其內(nèi)容列出了該服務(wù)器上所有的數(shù)據(jù)庫名稱。

2、更簡便的方法是使用USE語句,成功了就存在;不成功,就不存在。例如:

try

{

????m_pConnect->Execute("USE INSURANCE_2002",NULL

????????????????????????,adCmdTextadExecuteNoRecords);

}

catch(_com_error&e)

{//數(shù)據(jù)庫INSURANCE_2002不存在

}

7.4 判斷某個表是否存在

1、同樣判斷一個表是否存在,也可以用是否成功地打開它來判斷,十分方便,例如:

try

{

????m_pRecordset->Open("mytable"

????????????????????????,_variant_t((IDispatch *)m_pConnection,true)

????????????????????????,adOpenKeyset,adLockOptimistic,adCmdTable);

}

catch (_com_error &e)

{//該表不存在

}

2、要不然可以采用麻煩一點的辦法,就是在MS-SQL服務(wù)器上的每個數(shù)據(jù)庫中都有一個名為sysobjects的表,查看此表的內(nèi)容即知指定的表是否在該數(shù)據(jù)庫中。

3、同樣,每個數(shù)據(jù)庫中都有一個名為TABLES的視圖(View),查看此視圖的內(nèi)容即知指定的表是否在該數(shù)據(jù)庫中。

7.5 ADO鎖定整張表

Dim oConn As New ADODB.Connection

Dim oRs As New ADODB.Recordset

oConn.ConnectionTimeout = 15

oConn.Open 'Provider=SQLOLEDB.1;Password=***;Persist Security Info=True;User ID=***;Initial Catalog=XSSystem;Data Source=10.108.0.1'

oConn.CommandTimeout = 15

oConn.IsolationLevel = adXactSerializable

oConn.BeginTrans

oRs.CursorLocation = adUseClient

oRs.Open 'SELECT * FROM ShangYaoGuFenBuyTable with(tablockx) where ID='123' ', oConn, adOpenKeyset, adLockPessimistic

If oRs.RecordCount > 0 Then

MsgBox '已經(jīng)有一條記錄了'

Else

oRs.AddNew

oRs('id') = '123'

oRs.Update

End If

oRs.Close

oConn.CommitTrans '在此步驟之前,ShangYaoGuFenBuyTable整張表會被鎖住,其他用戶不能進行任何訪問

oConn.Close

Set oConn = Nothing

7.6 獲取記錄集行數(shù)

可以使用SQL語句:select count(*) from 表名

7.7 解決并發(fā)沖突

使用:Field 對象的 UnderlyingValue OriginalValue 屬性;Recordset Resync 方法和 Filter 屬性。

調(diào)用UpdateBatch后,一定要立即檢查Errors集合是否有錯誤。如果有錯誤,則應(yīng)檢查錯誤是否為并發(fā)沖突:

1、設(shè)置 Recordset Filter 屬性為adFilterConflictingRecords。若此時 RecordCount 屬性等于零,就說明錯誤是由沖突以外的其他原因引起的。

2、調(diào)用 Recordset Resync 方法,將 AffectRecords 參數(shù)設(shè)置為adAffectGroup,將 ResyncValues 參數(shù)設(shè)置為 adResyncUnderlyingValuesResync 方法將用來自基本數(shù)據(jù)庫中的數(shù)據(jù)刷新在當前 Recordset 對象中的數(shù)據(jù)。通過使用 adAffectGroup,可以確保只有使用當前篩選設(shè)置的情況下可見的記錄。

轉(zhuǎn)載于:https://www.cnblogs.com/hanford/p/6164335.html

總結(jié)

以上是生活随笔為你收集整理的ADO的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

91av大全 | 中文字幕亚洲精品在线观看 | 国产a国产a国产a | 日本福利视频在线 | 久久精品一区二区 | 国产美女网站在线观看 | 天天搞天天干天天色 | 在线观看中文字幕视频 | 国产破处视频在线播放 | 91麻豆精品国产91久久久久久 | 久久久精品在线观看 | 色国产视频| 久久9999久久免费精品国产 | 免费av在线播放 | 久草视频在线看 | 国产精品欧美一区二区三区不卡 | 欧美超碰在线 | 免费在线观看不卡av | 日韩偷拍精品 | 五月天亚洲激情 | 久久精品免费播放 | 国产亚洲免费的视频看 | 日韩欧美69 | av观看免费在线 | 天天操,夜夜操 | 久久影院午夜论 | av电影在线免费 | 国产精品国产亚洲精品看不卡15 | 国产999精品久久久久久 | 在线免费av观看 | 国产盗摄精品一区二区 | 在线观看亚洲视频 | 日韩中文字幕在线观看 | 久久精品在线免费观看 | 日韩伦理片hd | 草久中文字幕 | 日韩电影中文,亚洲精品乱码 | 区一区二区三区中文字幕 | av中文在线观看 | 中文区中文字幕免费看 | 日韩色中色 | 久久久免费 | 99亚洲精品 | 国产91全国探花系列在线播放 | 麻豆免费观看视频 | 99欧美精品 | 国产精品99久久久久人中文网介绍 | 国产福利中文字幕 | 五月婷婷色丁香 | 久久久久久电影 | 欧美一级黄色视屏 | 午夜在线国产 | 国产精品成人免费精品自在线观看 | 免费视频你懂得 | 欧美一区二区三区免费观看 | 99夜色| 99热国产精品| 午夜黄色一级片 | 香蕉在线视频观看 | 天天·日日日干 | 99资源网| 精品久久久一区二区 | 免费91麻豆精品国产自产在线观看 | 久久免费精品 | 免费看久久 | 中午字幕在线观看 | 日韩电影在线观看一区二区三区 | 日韩色区 | 激情视频免费观看 | 91九色视频观看 | av手机在线播放 | 国产亚洲资源 | 91精品人成在线观看 | 五月婷在线视频 | 日日操日日操 | 亚洲永久精品国产 | 波多野结衣电影一区二区三区 | 99久久99久国产黄毛片 | 免费在线观看黄色网 | 亚洲高清网站 | 国产精品久久久久永久免费观看 | 狠狠狠操 | 香蕉影院在线 | 亚洲精品tv| 中文字幕在线乱 | 国产精品视频全国免费观看 | 五月天亚洲综合 | 国产精品综合久久久久 | 天天狠狠干 | 99热精品国产 | 99视频在线观看视频 | 国产一区二区午夜 | 美女黄频在线观看 | 国产精品久久久久影院日本 | 久久婷婷综合激情 | 天天天色| 6080yy午夜一二三区久久 | 国产精品mm| 午夜性福利| 奇米影视777四色米奇影院 | 日韩精品一区在线观看 | 久久婷亚洲五月一区天天躁 | 免费观看av | 久久一区二区三区国产精品 | 蜜臀av性久久久久蜜臀aⅴ四虎 | 丁香 久久 综合 | 三级黄色三级 | 国产视频欧美视频 | 国内精品久久久久久久久 | 69久久久久久久 | 伊人成人久久 | 韩日精品在线观看 | 亚洲三区在线 | 成 人 黄 色 免费播放 | 国产手机在线观看视频 | 干干操操 | 国产精品久久久久久影院 | 久久99精品国产99久久 | 欧美精品网站 | 91视频91蝌蚪| 久久久精品一区二区三区 | 精品美女国产在线 | 久久99免费观看 | 亚洲黄色app | 依人成人综合网 | 国产精品成人a免费观看 | 免费精品国产va自在自线 | 国产欧美三级 | a级黄色片视频 | 97视频成人| 天天摸日日操 | 91私密保健 | 欧美一级免费 | 国产亲近乱来精品 | 91精品视频在线免费观看 | 国产网红在线观看 | 日韩理论在线播放 | 国产精品久久久久久久久久久杏吧 | 亚洲乱亚洲乱妇 | 免费网站看v片在线a | 欧美综合久久久 | 一级黄色在线免费观看 | 亚洲婷婷综合色高清在线 | 超碰人人超| 91精品秘密在线观看 | 在线观看精品黄av片免费 | 99 视频 高清 | 国产精品亚洲精品 | 亚洲国产精品日韩 | 黄色av免费 | 国产精品视频免费看 | 日日干夜夜操视频 | 国产精品自产拍在线观看蜜 | 国产xxxx做受性欧美88 | 欧美日韩高清一区二区 | 国产亚洲精品久久久久久电影 | 婷婷丁香国产 | 亚洲成人av电影 | 午夜色影院 | 日本性生活一级片 | 精品福利网站 | 在线观看视频一区二区三区 | 亚洲国产手机在线 | 久久精品中文 | 天天操天天干天天玩 | 国产精品久久久亚洲 | 在线免费色视频 | 在线播放av网址 | 深爱五月网 | 国产一区精品在线观看 | 色wwww| 精品国产免费人成在线观看 | 国产麻豆剧传媒免费观看 | 国产视频久久久 | 中文字幕av在线电影 | 国产精品va在线观看入 | 免费视频网 | 碰超在线 | 18av在线视频 | 丁香花在线观看视频在线 | 91精品视频网站 | 久久久首页 | 国产精品一区二区三区久久久 | 麻豆影视在线免费观看 | 国内精品久久久久久中文字幕 | 91精品视频播放 | 免费在线激情电影 | www.午夜色.com | 亚洲精品乱码久久久久久久久久 | 97成人资源站 | 国产色婷婷 | 99中文字幕在线观看 | 午夜精品久久久久久久99 | 五月婷香 | 在线观看黄色小视频 | 久久黄色影视 | 亚洲天堂va | 四季av综合网站 | 亚洲视频 中文字幕 | 国产精品乱码一区二三区 | 二区三区中文字幕 | 久久久久欧美精品999 | 99热手机在线 | 久久久久久久久精 | av在线免费播放 | 久久久999| 97色免费视频 | 91在线精品一区二区 | 亚洲三级性片 | 亚洲成人av免费 | 久久久久久99精品 | 亚洲激情影院 | 日韩美女av在线 | 久久不卡免费视频 | 国产精品地址 | 天天色宗合 | 国产人成免费视频 | 成人黄在线 | 韩国av不卡 | 青青草国产在线 | 国产精品永久久久久久久www | 黄免费在线观看 | 亚洲精品国精品久久99热 | 国产精品久久久久久久av电影 | 国产在线观 | 免费中文字幕视频 | 国产视频18 | 国产资源中文字幕 | 日韩综合一区二区 | 一本一道久久a久久综合蜜桃 | 久久九九国产视频 | 最新日韩在线观看 | 日韩欧美在线视频一区二区三区 | 国内精品久久久久久久 | 久久免费看a级毛毛片 | 波多野结衣精品视频 | 亚洲1区 在线 | 中文字幕91在线 | 最近中文字幕大全中文字幕免费 | 97成人免费视频 | avav片| 久久av在线 | 天天综合天天做 | 亚洲日本va午夜在线影院 | 五月婷婷综合在线 | 国产精品久久久电影 | 日韩啪啪小视频 | 久草在线免| 国产麻豆剧传媒免费观看 | av电影一区二区三区 | 激情网第四色 | 狠狠色丁香久久婷婷综合_中 | 激情网五月 | 国产亚洲精品久久久久久久久久 | 亚洲区色 | 亚洲成人家庭影院 | 色视频在线观看 | 成人资源站 | 日韩免费观看av | 日韩三级视频在线观看 | 日韩中文字幕亚洲一区二区va在线 | 在线播放 日韩专区 | 中文字幕在线国产精品 | 久久免费视频这里只有精品 | 午夜影院一区 | 日韩免费观看一区二区三区 | 亚洲国产免费看 | av中文字幕在线看 | 欧美一级日韩三级 | 国产一区二区午夜 | 久久五月天色综合 | 99久久99久久精品免费 | 中文在线中文a | 97在线免费观看 | 激情视频免费在线 | 一区二区三区四区精品视频 | 99久久久国产精品美女 | 日日夜操| 91视频免费国产 | 99久久久久久久久 | 在线欧美日韩 | 综合久久网站 | 91桃色国产在线播放 | 精品一区二区精品 | 中文字幕黄色网址 | 人人爽人人乐 | 国产 av 日韩| 色99网| 国产精品久久久久久久久久ktv | 国产精品女视频 | 99综合电影在线视频 | 国产这里只有精品 | 国产成人综 | 久草在线免费色站 | 日本乱视频 | 国产亚洲va综合人人澡精品 | 欧美亚洲久久 | 久热超碰| 国产精品久久久久久久久久东京 | 免费在线观看污 | 国产精品正在播放 | 久久视频99 | 成人久久亚洲 | 国产视频精品久久 | 亚洲视频久久久 | 国产97免费 | 日韩最新在线视频 | 黄av免费 | 中文字幕人成不卡一区 | 久久国产剧场电影 | 在线观看韩国av | 免费网站黄 | 免费在线观看成人 | 91高清免费| 免费看的国产视频网站 | 性色av香蕉一区二区 | 欧美日韩在线免费观看 | 国产精品日韩在线播放 | 中文字幕色婷婷在线视频 | 成年人免费在线观看网站 | 国产精品久久一区二区三区, | 国产精品亚洲人在线观看 | 日日碰狠狠添天天爽超碰97久久 | 国产精品高潮久久av | 精品久久久久久国产91 | 国产亚洲视频中文字幕视频 | 国产69精品久久99的直播节目 | 国产精品四虎 | 国产精品美女久久久久久2018 | 久久伦理电影 | 久久精品电影 | 国产精品一区二区无线 | 精品一区二区日韩 | 日韩影视在线观看 | 久草影视在线 | 亚洲第一香蕉视频 | 成人性生交视频 | 有码一区二区三区 | 福利视频区 | 亚洲高清视频一区二区三区 | 日韩在线视频看看 | 69国产精品视频免费观看 | 久久久久久久免费 | 99精品福利| a天堂一码二码专区 | 亚洲自拍偷拍色图 | 国产精品久久久久久久久久久免费 | 久久婷婷网 | 亚洲日本va午夜在线影院 | 一区二区三区视频网站 | 久久久久高清毛片一级 | 亚洲精品国产综合久久 | 免费看黄在线看 | 成年美女黄网站色大片免费看 | 国产剧情一区在线 | 在线中文字幕观看 | 欧美极品裸体 | 国产一区二区在线观看视频 | 99热精品久久 | 久久久在线免费观看 | av电影免费看 | 国产特级毛片aaaaaa | 婷婷在线免费观看 | 国产理论在线 | 日韩中文字幕免费在线观看 | 日韩欧美在线综合网 | 91精品毛片| 成人亚洲综合 | 欧美日韩视频一区二区三区 | 毛片网在线 | 久久草在线视频国产 | 国产自偷自拍 | 免费在线观看av网站 | 国产精品久久久区三区天天噜 | 亚洲精品国精品久久99热 | 91久久丝袜国产露脸动漫 | 91激情视频在线播放 | 欧美精品天堂 | 综合成人在线 | 欧美人操人 | 欧美色道 | 色综合www | 中文字幕一区二区三 | 99国产视频在线 | 夜夜躁日日躁狠狠久久av | 香蕉蜜桃视频 | 久久综合九色综合久久久精品综合 | 夜夜夜夜夜夜操 | 久久免费黄色 | 97碰在线| 婷婷去俺也去六月色 | 深夜免费福利网站 | 免费观看www7722午夜电影 | 欧美日韩69 | 久久综合色天天久久综合图片 | 国产视频久久久久 | 91黄色免费网站 | 久久99国产精品二区护士 | 麻豆传媒视频在线 | 日韩免费一级电影 | 久久久久国产成人免费精品免费 | 91视频黄色 | 干av在线 | 中文字幕日韩在线播放 | 国产小视频免费在线观看 | 一二三区高清 | 欧美日韩高清在线一区 | 在线小视频国产 | 欧美日本不卡高清 | 国产精品美女久久久久aⅴ 干干夜夜 | 免费观看成年人视频 | 五月天天天操 | 精品久久久免费视频 | 天天干夜夜夜 | 亚洲成人av片 | 美女黄频 | 91免费在线看片 | 青青啪 | 色综合天天综合网国产成人网 | 96国产在线 | 久久久国产精品人人片99精片欧美一 | 精品在线免费观看 | 福利一区在线视频 | 日韩乱色精品一区二区 | 免费观看完整版无人区 | 亚洲波多野结衣 | 免费试看一区 | 欧美久久久一区二区三区 | 中文字幕在线观看视频免费 | 婷婷久久网 | 免费在线中文字幕 | 成人精品一区二区三区中文字幕 | 国产a级精品 | 高潮久久久 | 国产又粗又长又硬免费视频 | 首页中文字幕 | 在线天堂中文在线资源网 | 国产91在线免费视频 | 综合天天| 国产精品丝袜在线 | 天天操天天弄 | 黄色小网站免费看 | 日韩二区在线观看 | 蜜臀av性久久久久蜜臀aⅴ流畅 | av一级片 | 亚洲精品一区二区三区新线路 | 欧美精品久久久久久久久老牛影院 | 亚洲 欧美 91| 五月开心婷婷网 | 中文字幕日韩精品有码视频 | 国产中文字幕在线视频 | 亚洲永久精品在线 | 中文字幕av影院 | 四虎国产精品成人免费影视 | 欧美日本国产在线观看 | 手机成人av在线 | 久久久影片| 国产97在线播放 | 九九久久影视 | 最近日本字幕mv免费观看在线 | 亚洲女人天堂成人av在线 | 亚一亚二国产专区 | 久久精品中文字幕一区二区三区 | 国产成人三级在线播放 | 国产精品wwwwww | 在线看不卡av | 亚洲欧美日韩不卡 | 狠狠狠狠狠狠狠狠 | 99爱国产精品 | 国产美女视频免费观看的网站 | 91香蕉视频污在线 | 天天射日 | 国产精品免费久久久久久久久久中文 | 亚洲精品视频在线观看网站 | 天天干天天射天天插 | 国产999精品久久久 免费a网站 | 五月婷在线播放 | 日韩午夜大片 | 99草视频在线观看 | 国产又粗又硬又爽的视频 | 国产精品久久久久久久久久久久午夜 | 色网免费观看 | 九九九热精品免费视频观看 | 国产黄色大全 | 久一久久| 国产精品久久嫩一区二区免费 | 玖玖视频精品 | 亚洲精品国精品久久99热一 | 91人人在线 | 九九精品视频在线看 | 午夜精品成人一区二区三区 | 欧美日韩视频免费看 | 九九免费在线看完整版 | 精品黄色在线观看 | 91视频免费看片 | 国产短视频在线播放 | 国产免费精彩视频 | 亚洲 欧洲 国产 精品 | 91一区在线观看 | 国产成人精品一二三区 | 日韩小视频 | 久久国产手机看片 | 亚洲精选视频免费看 | 国产精品一区二区三区四区在线观看 | 密桃av在线| 美女视频黄免费的久久 | 91久草视频 | 国产精品成人自拍 | 国产精品久久久久久婷婷天堂 | 在线看黄色的网站 | 亚洲久在线 | 在线免费观看黄色 | 国产亚洲成人网 | 欧美精品久久人人躁人人爽 | 中文字幕免费播放 | 91天堂在线观看 | 日日干综合| 国产不卡精品 | 色婷婷激情综合 | 日韩夜夜爽 | 亚洲最大在线视频 | 五月花婷婷 | 久爱精品在线 | 日日弄天天弄美女bbbb | 91成人精品在线 | 99精品欧美一区二区蜜桃免费 | 99热这里只有精品1 av中文字幕日韩 | 久久久久福利视频 | 在线免费黄色毛片 | a视频免费 | 99精品免费视频 | 一区二区三区免费在线观看视频 | 干 操 插 | 欧美日韩精品在线免费观看 | 日韩免费视频线观看 | 精品99视频 | 深爱激情开心 | 国产在线观看 | 精品日韩中文字幕 | 在线免费国产 | 久久婷婷网 | av黄色一级片 | 日本三级久久久 | 国产小视频免费在线观看 | 超碰在线免费97 | 美女精品网站 | 99精品在线免费视频 | 91av手机在线观看 | av高清在线| 免费看黄的 | 国产精品入口麻豆www | 国产高清在线免费观看 | 亚洲精品免费在线观看 | 人人射av| 日韩欧美一区二区三区在线观看 | 亚洲人视频在线 | 五月天婷婷丁香花 | 精品国产电影一区二区 | 手机在线看永久av片免费 | 免费在线观看日韩 | 日本一区二区三区视频在线播放 | 国产精品伦一区二区三区视频 | 在线岛国av | 综合精品久久久 | 黄色av影视| 亚洲午夜精品一区 | 国产在线日韩 | 国产精品久久免费看 | 免费亚洲电影 | 久热爱| 开心色婷婷| 欧美日韩亚洲在线 | 亚洲午夜av久久乱码 | 中文字幕 在线 一 二 | 碰超在线97人人 | 97电影在线 | 国产视频一二三 | 久久成人一区二区 | 国产人成在线视频 | 国产精品成人自产拍在线观看 | a级片在线播放 | av电影免费看 | 日韩专区在线观看 | 久久色网站 | 国产在线黄 | 91视频在线观看大全 | 精品久久久久免费极品大片 | 亚洲免费资源 | 激情综合狠狠 | 中文字幕免费不卡视频 | 色综合久久88色综合天天人守婷 | 久久国产三级 | 亚洲综合在 | 国产精品爽爽久久久久久蜜臀 | 综合天天色 | 亚洲成人黄色av | 国产在线黄 | 国产一级二级三级在线观看 | 99免费在线播放99久久免费 | 国产不卡在线 | 色婷婷导航 | 韩国一区二区三区在线观看 | 国产视频欧美视频 | 久久毛片高清国产 | 亚洲影院天堂 | 久热av| 国产视频一区二区三区在线 | 人人插人人玩 | 中文字幕在线播放日韩 | 亚洲一区久久久 | 日韩在线观看免费 | 99热这里只有精品在线观看 | 国产精品一区二区三区在线播放 | 欧美亚洲国产一卡 | 少妇精品久久久一区二区免费 | 激情开心色 | 国产淫片免费看 | 中文字幕在线不卡国产视频 | 手机av电影在线 | 久久草在线免费 | 欧美一级黄色视屏 | 在线天堂视频 | 精品国产一区二区三区久久久久久 | 天天干,天天草 | 国产精品18久久久久久久久 | 国产黄a三级三级 | 91福利免费 | 在线观看视频在线观看 | 国产精品永久 | 一区二区视频免费在线观看 | 99爱视频| 狠狠色伊人亚洲综合成人 | 亚洲国产97在线精品一区 | 国产在线观看91 | 国产精品网红福利 | 欧美亚洲三级 | 欧美一级在线看 | 国内视频在线观看 | 成人精品一区二区三区中文字幕 | 日韩性xxxx | 日韩精品专区在线影院重磅 | 综合天天网 | 亚洲天堂免费视频 | 亚洲欧美日韩国产一区二区 | 91大神在线观看视频 | 成人黄色电影在线观看 | 精品一区二三区 | 麻花豆传媒mv在线观看网站 | 97人人人人| 午夜三级毛片 | 91精品一区国产高清在线gif | 日韩欧美视频在线免费观看 | 日韩小视频| 一区二区三区四区五区在线 | 欧美另类sm图片 | 久久人视频 | 久草在线免费在线观看 | 亚洲一级电影 | 亚洲精品欧美专区 | 国产在线va | 91丨九色丨蝌蚪丨老版 | 亚洲一区二区三区毛片 | 天天色天天干天天 | 99久久夜色精品国产亚洲96 | 国产午夜在线观看视频 | 久久在草| 成人毛片一区 | 欧美日韩一二三四区 | 成人性生交大片免费看中文网站 | 免费在线电影网址大全 | 国产69精品久久99不卡的观看体验 | 亚洲影院一区 | 奇米先锋| 国产精品嫩草55av | 国产日韩欧美综合在线 | 久久免费99| 久久精品视频在线看 | 91精品视频一区二区三区 | 欧美色噜噜 | 99热最新精品 | 国产亚洲高清视频 | 99人久久精品视频最新地址 | 狠狠躁日日躁狂躁夜夜躁 | 天天射天天射天天 | 亚洲伦理一区 | 久久爱综合 | 日韩精品视频免费专区在线播放 | 在线观看国产一区二区 | www最近高清中文国语在线观看 | 成年人在线免费看视频 | 99久久精品免费看 | 日韩欧美视频在线观看免费 | 日韩免费二区 | 午夜影院日本 | 99色在线视频 | 国产91精品高清一区二区三区 | 日本在线成人 | 丁香婷婷亚洲 | 很黄很黄的网站免费的 | 国产五月天婷婷 | 国产精品99爱| 13日本xxxxxⅹxxx20| 丁香花中文在线免费观看 | 美女网站视频一区 | 夜夜躁日日躁狠狠久久88av | 国产在线精品观看 | 国产精品久久电影网 | 99se视频在线观看 | 久久久亚洲精华液 | 欧美日韩另类在线观看 | 亚洲h视频在线 | 99免费观看视频 | 国产精品一区二区av | 中文字幕永久免费 | 亚洲不卡av一区二区三区 | 99久久99久久综合 | 在线91色| 亚洲va欧洲va国产va不卡 | 91麻豆精品国产91久久久使用方法 | 成人在线观看免费 | 99免在线观看免费视频高清 | 久久久久久影视 | 中文字幕欧美日韩va免费视频 | 综合久久一本 | 色大片免费看 | 九九热只有这里有精品 | 在线观看岛国 | 中文字幕刺激在线 | 九九国产视频 | 免费高清看电视网站 | 国产精品自产拍在线观看网站 | 国产剧在线观看片 | 97超碰人人在线 | 久久精品久久精品久久精品 | 久久精品国产亚洲精品 | 在线视频一区二区 | 色婷婷九月 | 欧美激情va永久在线播放 | 激情导航 | 亚洲精品国偷自产在线91正片 | 99久久久久免费精品国产 | 日韩xxxxxxxxx | 国产精品91一区 | 亚洲在线激情 | 中文字幕在线精品 | 中文字幕在线免费观看视频 | 六月丁香社区 | 91九色在线观看视频 | 黄色国产成人 | 中文字幕色在线视频 | 96超碰在线 | 国产韩国精品一区二区三区 | 国产高清绿奴videos | 91精品中文字幕 | 天天操天| 亚洲视频一区二区三区在线观看 | 国产一区二区久久精品 | 色在线免费 | 久久99免费 | 久久成人视屏 | 免费在线观看国产黄 | 亚洲国产日韩欧美 | 天天爱天天操天天射 | 亚洲视频免费在线看 | 99久久99视频 | 不卡的av电影在线观看 | 正在播放国产精品 | 欧美激情视频在线观看免费 | 日韩激情影院 | 日韩一级理论片 | 97国产超碰在线 | 国产婷婷色 | 中文字幕在线视频一区 | 天天做天天爱天天综合网 | 亚洲美女精品视频 | 亚洲精品国偷拍自产在线观看蜜桃 | 成人日韩av | 久久久久精 | 99热这里只有精品免费 | 国产一区在线视频观看 | 婷婷综合伊人 | 国产精品不卡一区 | 欧美激情视频一区二区三区免费 | 超碰伊人网 | 一区二区国产精品 | 婷婷视频导航 | 日本激情动作片免费看 | 国产免费不卡av | 九九九电影免费看 | 日韩av片免费在线观看 | 欧美少妇影院 | 91看片淫黄大片在线播放 | 国产精品成人在线观看 | 国产一区免费在线 | 免费视频黄 | 九九免费在线观看 | 中文av日韩 | 在线a人片免费观看视频 | 天天艹天天 | 毛片1000部免费看 | 久久狠狠亚洲综合 | 日韩欧美视频一区 | 夜夜夜夜爽 | 日韩精品资源 | 色香蕉网 | 亚洲精品视频免费观看 | 97在线精品视频 | 免费av视屏 | 在线播放精品一区二区三区 | 日日干夜夜干 | 伊人成人久久 | 国产精品一区二区三区四 | 超碰av在线播放 | 国内精品久久久久久久 | 欧美日韩精品网站 | 国色天香第二季 | www.亚洲激情.com | 激情丁香月| 精品国产一区二区三区久久影院 | 久久影视中文字幕 | 国产码电影 | 久久久久成人精品亚洲国产 | 国产视频精品网 | 日韩欧美一级二级 | 久草视频中文在线 | 日韩精品免费一区二区三区 | 国产成人中文字幕 | 99久久精品国产一区 | 国产精品毛片一区视频播不卡 | 亚洲午夜av电影 | 999成人 | 超碰在线最新地址 | www五月天 | 久草精品视频在线播放 | 人人射人人爽 | 亚洲国产精品日韩 | 日韩电影中文,亚洲精品乱码 | 欧美一区免费在线观看 | 免费男女羞羞的视频网站中文字幕 | 天天干中文字幕 | 天天做天天爱天天综合网 | 一级黄色片在线播放 | 精品国偷自产国产一区 | 久久99国产精品免费网站 | 很黄很黄的网站免费的 | 国产精品久久久久久久久久三级 | 干av在线 | 日本黄色免费电影网站 | 右手影院亚洲欧美 | 五月婷丁香 | 久久在线免费观看 | 国产一区二区三区四区在线 | 92av视频| 国产一区二区综合 | 国产成人精品综合久久久久99 | 国产免费久久av | 日韩精品欧美专区 | 欧洲精品亚洲精品 | 日韩在线免费小视频 | 国内精品久久久久影院日本资源 | 四虎在线免费观看 | 亚洲黄色区 | 97精品国产97久久久久久免费 | 国产高清免费视频 | 国产在线观看91 | 日韩国产精品久久久久久亚洲 | 国内精品久久久久久久久久清纯 | 久久婷婷精品视频 | 日韩免费 | 精品国产欧美一区二区 | 天天综合中文 | 国产精品9999久久久久仙踪林 | 久草视频在线看 | 亚洲免费av电影 | 欧美性一级观看 | 婷婷色网站 | 日本资源中文字幕在线 | 国内精品美女在线观看 | 国产一区高清在线观看 | 天天操网站 | 香蕉成人在线视频 | 日韩精品不卡在线观看 | 六月丁香激情综合 | 最新久久久 | 国产精品久久99综合免费观看尤物 | 国产黄色免费看 | 天天草天天干天天射 | 免费观看www小视频的软件 | 精品免费久久 | 97狠狠干| 日产中文字幕 | 99热99re6国产在线播放 | 蜜桃av久久久亚洲精品 | 国产视频久久久 | 日本字幕网 | www.久久视频| a视频在线 | 欧洲亚洲国产视频 | 免费在线激情视频 | 欧美99热| 81国产精品久久久久久久久久 | 久久精品8 | 久热免费在线观看 | 99在线观看精品 | 亚洲精品视频在线观看免费视频 | 在线日本v二区不卡 | 国产精品成人在线 | 欧美网址在线观看 | 国产999精品久久久久久麻豆 | 国产精品mm| 日韩精品资源 | 激情小说久久 | 欧美一级裸体视频 | 91免费在线看片 | 久久久毛片| 成人午夜免费福利 | 激情视频免费在线 | 黄污视频网站 | 九九免费精品视频在线观看 | 国产精品99久久久久久久久久久久 | 成人在线小视频 | 狠狠色狠狠色综合日日92 | 亚洲精品成人av在线 | 99国产精品久久久久久久久久 | 精品在线观看免费 | 国产精品久久久久永久免费 | 91色国产在线 | 成人在线视频论坛 | 久久8| 国产精品亚洲人在线观看 | 超碰免费在线公开 | 91在线porny国产在线看 | 欧美性视频网站 | 精品特级毛片 | 日韩精品一区二区三区在线播放 | 在线成人观看 | 成人资源在线观看 | 99视频在线精品 | 日韩系列在线观看 | 在线成人性视频 | 探花视频在线版播放免费观看 | 精品视频免费久久久看 | 在线欧美最极品的av | 在线 国产一区 | 欧美亚洲精品在线观看 | 午夜精品久久久久久中宇69 | 久草在线中文视频 | 伊人婷婷色 | 欧美久久久久 | 国产精品毛片一区二区三区 | 国产经典三级 | 国产高清免费av | www日韩| 日韩精品视频在线观看免费 | 久久国产精品久久w女人spa | 国产精品s色 | 精品日韩在线一区 | 久久精品欧美 | 国产丝袜美腿在线 | 夜夜操天天干, | 特级毛片爽www免费版 | 91麻豆看国产在线紧急地址 | 在线观看视频h | 天天色天天上天天操 | 国产成人精品免高潮在线观看 | 日韩免费在线网站 | 亚洲一二区视频 | 91精品国产综合久久婷婷香蕉 | 国产精品a级 | 成 人 黄 色 视频 免费观看 | 久久综合色婷婷 | 中文字幕视频 | 亚洲成a人片综合在线 | 精品在线观看国产 | 国产亚洲一区二区在线观看 | 亚洲 欧洲av| 手机看片国产日韩 | 色爱成人网 | 亚洲黄电影| 91伊人影院 | 特级aaa毛片 | 欧美成人亚洲成人 | 伊人www22综合色 | 在线观看自拍 | 91成人精品在线 | 亚洲精品一区二区三区四区高清 | 午夜色婷婷 | 久久免费av电影 | 国产在线观看黄 | 天天射天天干天天操 | 国产成人综合在线观看 | 91麻豆精品国产91久久久久 | 亚洲h色精品| 免费在线黄色av | 看国产黄色大片 | 国产在线精品国自产拍影院 | 中文字幕精品一区 | 三级av网|