??xml version="1.0" encoding="utf-8" standalone="yes"?>久久人人爽人人爽人人AV东京热,欧美一级久久久久久久大,久久精品一区二区三区不卡http://www.shnenglu.com/ivenher/articles/16638.html爱饭?/dc:creator>爱饭?/author>Wed, 20 Dec 2006 03:24:00 GMThttp://www.shnenglu.com/ivenher/articles/16638.htmlhttp://www.shnenglu.com/ivenher/comments/16638.htmlhttp://www.shnenglu.com/ivenher/articles/16638.html#Feedback0http://www.shnenglu.com/ivenher/comments/commentRss/16638.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/16638.html原方法如下:
case VT_DECIMAL: 
             {
                  
double val = var.decVal.Lo32;
                                     
                    val 
*= (var.decVal.sign == 128)? -1 : 1;
                    val 
/= pow(10, var.decVal.scale); 
                    CString strFormat;
                    strFormat.Format(
"%d", var.decVal.scale);
                    strFormat 
= "%."+strFormat+"f";
                                         strValue.Format(strFormat, val);

                                 
break;
             }


转过多次没出什么事pD代码可以用。结果问题就出在q段代码?br />

///问题所?/span>
double val = var.decVal.Lo32;

//应改为?/span>
 double val=var.decVal.Lo64;

当数据较大时数据被截断,灵异事g出C?

]]>
调用存储q程http://www.shnenglu.com/ivenher/articles/9655.html爱饭?/dc:creator>爱饭?/author>Mon, 10 Jul 2006 11:34:00 GMThttp://www.shnenglu.com/ivenher/articles/9655.htmlhttp://www.shnenglu.com/ivenher/comments/9655.htmlhttp://www.shnenglu.com/ivenher/articles/9655.html#Feedback1http://www.shnenglu.com/ivenher/comments/commentRss/9655.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/9655.html  ptrCmd->CommandType = adCmdStoredProc;
  ptrCmd->Execute(NULL,NULL,adCmdStoredProc);

]]>
Visual C++ ADO数据库编E入门(下)http://www.shnenglu.com/ivenher/articles/2294.html爱饭?/dc:creator>爱饭?/author>Fri, 30 Dec 2005 10:32:00 GMThttp://www.shnenglu.com/ivenher/articles/2294.htmlhttp://www.shnenglu.com/ivenher/comments/2294.htmlhttp://www.shnenglu.com/ivenher/articles/2294.html#Feedback0http://www.shnenglu.com/ivenher/comments/commentRss/2294.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/2294.html10、邦定数?BR>
  定义一个绑定类Q将其成员变量绑定到一个指定的记录集,以方便于讉K记录集的字段倹{?BR>
  (1). 从CADORecordBindingzZ个类Q?BR>
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;
};

  其中要l定的字D与变量名用BEGIN_ADO_BINDING宏关联v来。每个字D对应于两个变量Q一个存攑֭D늚|另一个存攑֭D늚状态。字D는?开始的序号表示Q如1Q?Q?{等?BR>
  特别要注意的是:如果要绑定的字段是字W串cdQ则对应的字W数l的元素个数一定要比字D长度大2Q比如m_szau_fname[22]Q其l定的字Dau_fname的长度实际是20Q,不这L定就会失败。我分析多出?可能是ؓ了存攑֭W串l尾的空字符null和BSTR字符串开头的一个字Q表CBSTR的长度)。这个问题对于初学者来说可能是一个意想不到的问题?BR>
  CADORecordBindingcȝ定义在icrsint.h文g里,内容是:

class CADORecordBinding
{
public:
STDMETHOD_(const ADO_BINDING_ENTRY*, GetADOBindingEntries) (VOID) PURE;
};

BEGIN_ADO_BINDING宏的定义也在icrsint.h文g里,内容是:
#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文g里:
#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文g里:
#define END_ADO_BINDING() {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\
return rgADOBindingEntries;}

   (2). l定

_RecordsetPtr Rs1;
IADORecordBinding *picRs=NULL;
CCustomRs rs;
......
Rs1->QueryInterface(__uuidof(IADORecordBinding),
(LPVOID*)&picRs));
picRs->BindToRecordset(&rs);

  z出的cd通过IADORecordBinding接口才能l定Q调用它的BindToRecordsetҎp了?BR>
  (3). rs中的变量x当前记录字段的?BR>
//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(&rs)); // Add change to the batch
Rs1->MoveNext();
}
Rs1->Filter = (long) adFilterNone;
......
if (picRs) picRs->Release();
Rs1->Close();
pConn->Close();

  只要字段的状态是adFldOKQ就可以讉K。如果修改了字段Q不要忘了先调用picRs的UpdateQ注意不是Recordset的UpdateQ,然后才关闭,也不要忘了释放picRsQ即picRs->Release();Q?BR>
  (4). 此时q可以用IADORecordBinding接口d新纪?BR>
if(FAILED(picRs->AddNew(&rs)))
......

  11. 讉K长数?BR>
  在Microsoft SQL中的长数据包括text、image{这样长cd的数据,作ؓ二进制字节来对待?BR>
  可以用Field对象的GetChunk和AppendChunkҎ来访问。每ơ可以读出或写入全部数据的一部分Q它会记住上ơ访问的位置。但是如果中间访问了别的字段后,又得从头来了?BR>
  L下面的例子:

//写入一张照片到数据库:
VARIANT varChunk;
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];

//VT_ARRAY ?VT_UI1
CFile f("h:\\aaa.jpg",Cfile::modeRead);
BYTE bVal[ChunkSize+1];
UINT uIsRead=0;
//Create a safe array to store the array of BYTES
while(1)
{
uIsRead=f.Read(bVal,ChunkSize);
if(uIsRead==0)break;
rgsabound[0].cElements =uIsRead;
rgsabound[0].lLbound = 0;
psa = SafeArrayCreate(VT_UI1,1,rgsabound);
for(long index=0;index<uIsRead;index++)
{
if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index])))
::MessageBox(NULL,"啊,又出毛病了?,"提示",MB_OK ?MB_ICONWARNING);
}
varChunk.vt = VT_ARRAY│VT_UI1;
varChunk.parray = psa;
try{
m_pRecordset->Fields->GetItem("photo")->AppendChunk(varChunk);
}
catch (_com_error &e)
{
CString str=(char*)e.Description();
::MessageBox(NULL,str+"\n又出毛病了?,"提示",MB_OK ?MB_ICONWARNING);
}
::VariantClear(&varChunk);
::SafeArrayDestroyData( psa);
if(uIsRead<ChunkSize)break;
}//while(1)
f.Close();

//从数据库M张照片:
CFile f;
f.Open("h:\\bbb.jpg",Cfile::modeWrite│Cfile::modeCreate);
long lPhotoSize = m_pRecordset->Fields->Item["photo"]->ActualSize;
long lIsRead=0;

_variant_t varChunk;
BYTE buf[ChunkSize];
while(lPhotoSize>0)
{
lIsRead=lPhotoSize>=ChunkSize? ChunkSize:lPhotoSize;
varChunk = m_pRecordset->Fields->
Item["photo"]->GetChunk(lIsRead);
for(long index=0;index<lIsRead;index++)
{
::SafeArrayGetElement(varChunk.parray,&index,buf+index);
}
f.Write(buf,lIsRead);
lPhotoSize-=lIsRead;
}//while()
f.Close();


  12. 使用SafeArray问题

  学会使用SafeArray也是很重要的Q因为在ADO~程中经常要用。它的主要目的是用于automation中的数组型参数的传递。因为在|络环境中,数组是不能直接传递的Q而必d其包装成SafeArray。实质上SafeArray是通常的数l增加一个描q符Q说明其l数、长度、边界、元素类型等信息。SafeArray也ƈ不单独用,而是其再包装到VARIANTcd的变量中Q然后才作ؓ参数传送出厅R在VARIANT的vt成员的值如果包含VT_ARRAY?..,那么它所装的就是一个SafeArrayQ它的parray成员x指向SafeArray的指针。SafeArray中元素的cd可以是VARIANT能封装的McdQ包括VARIANTcd本n?

  使用SafeArray的具体步骤:

  Ҏ一Q?BR>
  包装一个SafeArrayQ?BR>
  (1). 定义变量Q如Q?BR>
VARIANT varChunk;
SAFEARRAY *psa;
SAFEARRAYBOUND rgsabound[1];

  (2). 创徏SafeArray描述W:

uIsRead=f.Read(bVal,ChunkSize);//read array from a file.
if(uIsRead==0)break;
rgsabound[0].cElements =uIsRead;
rgsabound[0].lLbound = 0;
psa = SafeArrayCreate(VT_UI1,1,rgsabound);

  (3). 攄数据元素到SafeArrayQ?BR>
for(long index=0;index<uIsRead;index++)
{
if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index])))
::MessageBox(NULL,"出毛病了?,"提示",MB_OK ?MB_ICONWARNING);
}

  一个一个地放,挺麻烦的?BR>
  (4). 装到VARIANT内:

varChunk.vt = VT_ARRAY│VT_UI1;
varChunk.parray = psa;

  q样可以将varChunk作ؓ参数传送出M?BR>
  dSafeArray中的数据的步骤:

  (1). 用SafeArrayGetElement一个一个地?BR>
BYTE buf[lIsRead];
for(long index=0;index<lIsRead;index++)
{
::SafeArrayGetElement(varChunk.parray,&index,buf+index);
}

  p到缓冲区buf里了?BR>
  Ҏ二:

  使用SafeArrayAccessData直接dSafeArray的缓冲区Q?BR>
  (1). ȝ冲区Q?BR>
BYTE *buf;
SafeArrayAccessData(varChunk.parray, (void **)&buf);
f.Write(buf,lIsRead);
SafeArrayUnaccessData(varChunk.parray);

  (2). 写缓冲区Q?BR>
BYTE *buf;
::SafeArrayAccessData(psa, (void **)&buf);
for(long index=0;index<uIsRead;index++)
{
buf[index]=bVal[index];
}
::SafeArrayUnaccessData(psa);

varChunk.vt = VT_ARRAY│VT_UI1;
varChunk.parray = psa;

  q种ҎdSafeArray都可以,它直接操USafeArray的数据缓冲区Q比用SafeArrayGetElement和SafeArrayPutElement速度快。特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData(psa)Q否则会出错的?BR>
  13. 使用书签( bookmark )

  书签可以唯一标识记录集中的一个记录,用于快速地当前记录移回到已访问过的记录,以及q行qo{等。Provider会自动ؓ记录集中的每一条记录生一个书{,我们只需要用它p了。我们不能试图显C、修Ҏ比较书签。ADO用记录集的Bookmark属性表C当前记录的书签?BR>
  用法步骤Q?BR>
  (1). 建立一个VARIANTcd的变?BR>
_variant_t VarBookmark;

  (2). 当前记录的书签值存入该变量

  也就是记录集的Bookmark属性的当前倹{?BR>
VarBookmark = rst->Bookmark;

  (3). q回到先前的记录

  保存的书签D|到记录集的书签属性中Q?BR>
// Check for whether bookmark set for a record
if (VarBookmark.vt == VT_EMPTY)
printf("No Bookmark set!\n");
else
rst->Bookmark = VarBookmark;

  讄完后Q当前记录即会移动到该书{指向的记录?BR>

  14、设|过滤条?BR>
  Recordset对象的Filter属性表CZ当前的过滤条件。它的值可以是以AND或ORq接h的条件表辑ּQ不含WHERE关键字)、由书签l成的数l或ADO提供的FilterGroupEnum枚D倹{ؓFilter属性设|新值后Recordset的当前记录指针会自动Ud到满滤条件的W一个记录。例如:

rst->Filter = _bstr_t ("姓名='赵薇' AND 性别=’女?);

  在用条件表辑ּ时应注意下列问题Q?BR>
  Q?Q、可以用圆括L成复杂的表达?BR>
  例如Q?BR>
rst->Filter = _bstr_t ("(姓名='赵薇' AND 性别=’女? OR AGE<25");

  但是微Y不允许在括号内用ORQ然后在括号外用ANDQ例如:

rst->Filter = _bstr_t ("(姓名='赵薇' OR 性别=’女? AND AGE<25");

  必须修改为:

rst->Filter = _bstr_t ("(姓名='赵薇' AND AGE<25) OR (性别=’女?AND AGE<25)");

  Q?Q、表辑ּ中的比较q算W可以是LIKE

  LIKE后被比较的是一个含有通配W?的字W串Q星可Cq个L的字W?BR>
  字符串的首部和尾部可以同时带星号*

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

  也可以只是尾部带星号Q?BR>
rst->Filter = _bstr_t ("姓名 LIKE '?' ");

  Filter属性值的cd是VariantQ如果过滤条件是׃{成的数组Q则需该数组转换为SafeArrayQ然后再装C个VARIANT或_variant_t型的变量中,再赋lFilter属性?BR>
  15、烦引与排序

  Q?Q、徏立烦?BR>
  当以某个字段为关键字用FindҎ查找ӞZ加快速度可以以该字段为关键字在记录集内部临时建立索引。只要将该字D늚Optimize属性设|ؓtrue卛_Q例如:

pRst->Fields->GetItem("姓名")->Properties->
GetItem("Optimize")->PutValue("True");
pRst->Find("姓名 = '赵薇'",1,adSearchForward);
......
pRst->Fields->GetItem("姓名")->Properties->
GetItem("Optimize")->PutValue("False");
pRst->Close();

  说明QOptimize属性是由Provider提供的属性(在ADO中称为动态属性)QADO本n没有此属性?BR>
  Q?Q、排?BR>
  要排序也很简单,只要把要排序的关键字列表讄到Recordset对象的Sort属性里卛_Q例如:

pRstAuthors->CursorLocation = adUseClient;
pRstAuthors->Open("SELECT * FROM mytable",
_variant_t((IDispatch *) pConnection),
adOpenStatic, adLockReadOnly, adCmdText);
......
pRst->Sort = "姓名 DESC, q龄 ASC";

  关键字(卛_D名Q之间用逗号隔开Q如果要以某关键字降序排序,则应在该关键字后加一I格Q再加DESCQ如上例Q。升序时ASC加不加无所谓。本操作是利用烦引进行的Qƈ未进行物理排序,所以效率较高?BR>但要注意Q在打开记录集之前必d记录集的CursorLocation属性设|ؓadUseClientQ如上例所C。Sort属性值在需要时随时可以修改?BR>
  16、事务处?BR>
  ADO中的事务处理也很单,只需分别在适当的位|调用Connection对象的三个方法即可,q三个方法是Q?BR>
  Q?Q、在事务开始时调用

pCnn->BeginTrans();

  Q?Q、在事务l束q成功时调用

pCnn->CommitTrans ();

  Q?Q、在事务l束q失败时调用

pCnn->RollbackTrans ();

  在用事务处理时Q应量减小事务的范_卛_从事务开始到l束Q提交或回滚Q之间的旉间隔Q以便提高系l效率。需要时也可在调用BeginTrans()Ҏ之前Q先讄Connection对象的IsolationLevel属性|详细内容参见MSDN中有关ADO的技术资料?BR>
  三、用ADO~程常见问题解答

  以下均是针对MS SQL 7.0~程时所遇问题进行讨论?BR>
  1、连接失败可能原?BR>
  Enterprise Managemer内,打开服务器的属性对话框Q在Security选项卡中Q有一个选项Authentication?BR>
  如果该选项是Windows NT onlyQ则你的E序所用的q接字符串就一定要包含Trusted_Connection参数Qƈ且其值必MؓyesQ如Q?BR>
"Provider=SQLOLEDB;Server=888;Trusted_Connection=yes"
";Database=master;uid=lad;";

  如果不按上述操作Q程序运行时q接必然p|?BR>
  如果Authentication选项是SQL Server and Windows NTQ则你的E序所用的q接字符串可以不包含Trusted_Connection参数Q如Q?BR>
"Provider=SQLOLEDB;Server=888;Database=master;uid=lad;pwd=111;";

  因ؓADOl该参数取的默认值就是noQ所以可以省略。我认ؓq是取默认值比较安全一些?BR>
  2、改变当前数据库的方?BR>
  使用Tansct-SQL中的USE语句卛_?BR>
  3、如何判断一个数据库是否存在

  (1)、可打开master数据库中一个叫做SCHEMATA的视图,其内容列Z该服务器上所有的数据库名U?BR>
  (2) 、更便的Ҏ是用USE语句Q成功了存在;不成功,׃存在。例如:

try{
m_pConnect->Execute ( _bstr_t("USE INSURANCE_2002"),NULL,
adCmdText│adExecuteNoRecords );
}
catch (_com_error &e)
{
blSuccess=FALSE;
CString str="数据库INSURANCE_2002不存在!\n";
str+=e.Description();
::MessageBox(NULL,str,"警告",MB_OK ?MB_ICONWARNING);
}

  4、判断一个表是否存在

  Q?Q、同样判断一个表是否存在Q也可以用是否成功地打开它来判断Q十分方便,例如Q?BR>
try{
m_pRecordset->Open(_variant_t("mytable"),
_variant_t((IDispatch *)m_pConnection,true), adOpenKeyset,
adLockOptimistic, adCmdTable);
}
catch (_com_error &e)
{
::MessageBox(NULL,"该表不存在?,"提示",MB_OK ?MB_ICONWARNING);
}

  (2)、要不然可以采用ȝ一点的办法Q就是在MS-SQL服务器上的每个数据库中都有一个名为sysobjects的表Q查看此表的内容即知指定的表是否在该数据库中?BR>
  (3)、同P每个数据库中都有一个名为TABLES的视?View)Q查看此视图的内容即知指定的表是否在该数据库中?BR>
  5、类型{换问?BR>
  Q?Q、类型VARIANT_BOOL

  cdVARIANT_BOOL{h于shortcd。The VARIANT_BOOL is equivalent to short. see it's definition below:
typdef short VARIANT_BOOL

  Q?Q、_com_ptr_tcȝcd转换

  _ConnectionPtr可以自动转换成IDspatch*cdQ这是因为_ConnectionPtr实际上是_com_ptr_tcȝ一个实例,而这个类有此cd转换函数?BR>
  同理Q_RecordsetPtr和_CommandPtr也都可以q样转换?BR>
  Q?Q、_bstr_t和_variant_tc?BR>
  在ADO~程Ӟ_bstr_t和_variant_tq两个类很有用,省去了许多BSTR和VARIANTcd转换的麻烦?BR>
  6、打开记录集时的问?BR>
  在打开记录集时Q在调用Recordset的OpenҎӞ其最后一个参数里一定不能包含adAsyncExecuteQ否则将因ؓ是异步操作,在读取数据时无法d数据?BR>
  7、异常处理问?BR>
  Ҏ有调用ADO的语句一定要用try和catch语句捕捉异常Q否则在发生异常ӞE序会异帔R出?BR>
  8、用SafeArray问题

  在初学用中Q我NC个伤脑筋的问题,一定要注意Q?BR>
  在定义了SAFEARRAY的指针后Q如果打重复用多ơ,则在中间可以调用::SafeArrayDestroyData释放数据Q但决不能调?:SafeArrayDestroyDescriptorQ否则必然出错,即调用SafeArrayCreate也不行。例如:

SAFEARRAY *psa;
......
//When the data are no longer to be used:
::SafeArrayDestroyData( psa);

  我分析在定义psa指针Ӟ一个SAFEARRAY的实例(也就是SAFEARRAY描述W)也同时被自动建立了。但是只要一调用::SafeArrayDestroyDescriptorQ描q符p销毁了?BR>
  所以我认ؓ::SafeArrayDestroyDescriptor可以Ҏ׃调用Q即使调用也必须在最后调用?BR>
  9、重复用命令对象问?BR>
  一个命令对象如果要重复使用多次Q尤其是带参数的命oQ,则在W一ơ执行之前,应将它的Prepared属性设|ؓTRUE。这样会使第一ơ执行减慢,但却可以使以后的执行全部加快?BR>
  10、绑定字W串型字D问?BR>
  如果要绑定的字段是字W串cdQ则对应的字W数l的元素个数一定要比字D长度大2Q比如m_szau_fname[22]Q其l定的字Dau_fname的长度实际是20Q,不这L定就会失败?BR>
  11、用AppendChunk的问?BR>
  当用AddNewҎ刚刚向记录集内添加一个新记录之后Q不能首先向一个长数据字段QimagecdQ写入数据,必须先向其他字段写入q数据之后,才能调用AppendChunk写该字段Q否则出错。也是_AppendChunk不能紧接在AddNew之后。另外,写入其他字段后还必须紧接着调用AppendChunkQ而不能调用记录集的UpdateҎ后,才调用AppendChunkQ否则调用AppendChunk时也会出错。换句话_是必须AppendChunk在前QUpdate在后。因而这个时候就不能使用带参数的AddNew了,因ؓ带参数的AddNew会自动调用记录集的UpdateQ所以AppendChunkp到Update的后面了Q就只有出错了!因此Q这时应该用不带参数的AddNew?BR>
  我推这可能是MS SQL 7.0的问题,在MS SQL 2000中则不存在这些问题,但是AppendChunk仍然不能在Update之后?BR>
  四、小l?/B>

  一般情况下QConnection和Command的Execute用于执行不生记录集的命令,而Recordset的Open用于产生一个记录集Q当然也不是l对的。特别Command主要是用于执行参数化的命令,可以直接由Command对象执行Q也可以Command对象传递给Recordset的Open?/SPAN>



]]>
Visual C++ ADO数据库编E入门(上)http://www.shnenglu.com/ivenher/articles/2293.html爱饭?/dc:creator>爱饭?/author>Fri, 30 Dec 2005 10:31:00 GMThttp://www.shnenglu.com/ivenher/articles/2293.htmlhttp://www.shnenglu.com/ivenher/comments/2293.htmlhttp://www.shnenglu.com/ivenher/articles/2293.html#Feedback0http://www.shnenglu.com/ivenher/comments/commentRss/2293.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/2293.html  ADO 是目前在Windows环境中比较流行的客户端数据库~程技术。ADO是徏立在OLE DB底层技术之上的高~程接口Q因而它兼具有强大的数据处理功能Q处理各U不同类型的数据源、分布式的数据处理等{)和极其简单、易用的~程接口Q因而得Cq泛的应用。而且按微软公司的意图QOLE DB和ADO逐步取代 ODBC和DAO。现在介lADO各种应用的文章和书籍有很多,本文着重站在初学者的角度Q简要探讨一下在VC++中用ADO~程时的一些问题。我们希望阅L文之前,您对ADO技术的基本原理有一些了解?BR>
  一、在VC++中用ADO~程

  ADO实际上就是由一lAutomation对象构成的组Ӟ因此可以象用其它Q何Automation对象一样用ADO。ADO中最重要的对象有三个QConnection、Command和RecordsetQ它们分别表C接对象、命令对象和记录集对象。如果您熟悉使用MFC中的ODBCc(CDatabase、CRecordset)~程Q那么学习ADO~程十分容易了?BR>
  使用ADO~程时可以采用以下三U方法之一Q?BR>
  1、用预处理指o#import

#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "EndOfFile")

  但要注意不能攑֜stdAfx.h文g的开_而应该放在所有include指o的后面。否则在~译时会出错?BR>E序在编译过E中QVC++会读出msado15.dll中的cd库信息,自动产生两个该类型库的头文g和实现文件msado15.tlh和msado15.tliQ在您的Debug或Release目录下)。在q两个文仉定义了ADO的所有对象和ҎQ以及一些枚丑֞的常量等。我们的E序只要直接调用q些Ҏp了,与用MFC中的COleDispatchDriverc调用Automation对象十分cM?BR>
  2、用MFC中的CIDispatchDriver

  是通过dmsado15.dll中的cd库信息,建立一个COleDispatchDrivercȝzc,然后通过它调用ADO对象?BR>
  3、直接用COM提供的API

  如用如下代码:

CLSID clsid;
HRESULT hr = ::CLSIDFromProgID(L"ADODB.Connection", &clsid);
if(FAILED(hr))
{...}
::CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IDispatch, (void **)
&pDispatch);
if(FAILED(hr))
{...}

  以上三种ҎQ第一和第二种cMQ可能第一U好用一些,W三U编E可能最ȝ。但可能W三U方法也是效率最高的Q程序的寸也最,q且对ADO的控制能力也最强?BR>
  据微软资料介l,W一U方法不支持Ҏ调用中的默认参数Q当然第二种Ҏ也是q样Q但W三U就不是q样了。采用第三种Ҏ的水q也最高。当你需要绕qADO而直接调用OLE DB底层的方法时Q就一定要使用W三U方法了?BR>
  ADO~程的关键,是熟练地运用ADO提供的各U对?object)、方?method)、属?property)和容器(collectionQ。另外,如果是在MS SQL或Oracle{大型数据库上编E,q要能熟l用SQL语言?BR>

  二、?importҎ的编E步?/B>

  q里您?import的方法,因ؓ它易学、易用,代码也比较简z?BR>
  1?d#import指o

  打开stdafx.h文gQ将下列内容d到所有的include指o之后Q?BR>
#include <icrsint.h> //Include support for VC++ Extensions
#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "adoEOF")

  其中icrsint.h文g包含了VC++扩展的一些预处理指o、宏{的定义Q用于COM~程时用?BR>
  2、定义_ConnectionPtr型变量,q徏立数据库q接

  建立了与数据库服务器的连接后Q才能进行其他有x据库的访问和操作。ADO使用Connection对象来徏立与数据库服务器的连接,所以它相当于MFC中的CDatabasecR和CDatabasecMP调用Connection对象的OpenҎ卛_建立与服务器的连接?BR>
  数据cd _ConnectionPtr实际上就是由cL板_com_ptr_t而得到的一个具体的实例c,其定义可以到msado15.tlh、comdef.h 和comip.hq三个文件中扑ֈ。在msado15.tlh中有Q?BR>
_COM_SMARTPTR_TYPEDEF(_Collection, __uuidof(_Collection));

  l宏扩展后就得到了_ConnectionPtrcR_ConnectionPtrcd装了Connection对象的Idispatch接口指针Q及一些必要的操作。我们就是通过q个指针来操UConnection对象。类似地Q后面用到的_CommandPtr和_RecordsetPtrcd也是q样得到的,它们分别表示命o对象指针和记录集对象的指针?BR>
  Q?Q、连接到MS SQL Server

  注意q接字符串的格式Q提供正的q接字符串是成功q接到数据库服务器的W一步,有关q接字符串的详细信息参见微YMSDN Library光盘?BR>
  本例q接字符串中的server_nameQdatabase_nameQuser_name和password在编E时都应该替换成实际的内宏V?BR>
_ConnectionPtr pMyConnect=NULL;
HRESULT hr=pMyConnect.CreateInstance(__uuidof(Connection)));
if(FAILED(hr))return;

_bstr_t strConnect="Provider=SQLOLEDB; Server=server_name;"
"Database=database_name; uid=user_name; pwd=password;";
//connecting to the database server now:
try{pMyConnect->Open(strConnect,"","",NULL);}
catch (_com_error &e)
{
::MessageBox(NULL,e.Description(),"警告",MB_OK ?MB_ICONWARNING);
}

  注意Connection对象的OpenҎ中的q接字符串参数必LBSTR或_bstr_tcd。另外,本例是直接通过OLE DB Provider建立q接Q所以无需建立数据源?BR>
  Q?Q、通过ODBC Driverq接到Database Serverq接字符串格式与直接用ODBC~程时的差不多:

_bstr_t strConnect="DSN=datasource_name; Database=database_name; uid=user_name; pwd=password;";

  此时与ODBC~程一P必须先徏立数据源?BR>
  3、定义_RecordsetPtr型变量,q打开数据?BR>
  定义_RecordsetPtr型变量,然后通过它调用Recordset对象的OpenҎQ即可打开一个数据集。所以Recordset对象与MFC中的CRecordsetcȝ|它也有当前记录、当前记录指针的概念。如Q?BR>
_RecordsetPtr m_pRecordset;
if(!FAILED(m_pRecordset.CreateInstance( __uuidof( Recordset )))
{
m_pDoc->m_initialized=FALSE;
return;
}

try{
m_pRecordset->Open(_variant_t("mytable"),
_variant_t((IDispatch *)pMyConnect,true), adOpenKeyset,
adLockOptimistic, adCmdTable);
}
catch (_com_error &e)
{
::MessageBox(NULL,"无法打开mytable表?,"提示",
MB_OK ?MB_ICONWARNING);
}

  Recordset对象的OpenҎ非常重要Q它的第一个参数可以是一个SQL语句、一个表的名字或一个命令对象等{;W二个参数就是前面徏立的q接对象的指针。此外,用Connection和Command对象的ExecuteҎ也能得到记录集,但是只读的?BR>

  4、读取当前记录的数据

  我认取数据的最方便的方法如下:

try{
m_pRecordset->MoveFirst();
while(m_pRecordset->adoEOF==VARIANT_FALSE)
{
//Retrieve column's value:
CString sName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem
(_variant_t("name"))->Value);
short cAge=(short)(m_pRecordset->Fields->GetItem
(_variant_t("age"))->Value);
//Do something what you want to do:
......
m_pRecordset->MoveNext();
}
}//try
catch (_com_error &e)
{
CString str=(char*)e.Description();
::MessageBox(NULL,str+"\n又出毛病了?,"提示",
MB_OK ?MB_ICONWARNING);
}

  本例中的name和age都是字段名,d的字D值分别保存在sName和cAge变量内。例中的Fields是Recordset对象的容器,GetItemҎq回的是Field对象Q而Value则是Field对象的一个属性(卌字段的|。通过此例Q应掌握操纵对象属性的Ҏ。例如,要获得Field 对象的Value属性的值可以直接用属性名Value来引用它Q如上例Q,但也可以调用GetҎQ例如:

CString sName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem
(_variant_t("name"))->GetValue());

  从此例还可以看到Q判断是否到达记录集的末,使用记录集的adoEOF属性,其D为真卛_了结,反之则未到。判断是否到达记录集开_则可用BOF属性?BR>
  另外Q读取数据还有一个方法,是定义一个绑定的c,然后通过l定的变量得到字D|详见后面的介l)?BR>
  5、修Ҏ?BR>
  Ҏ一Q?BR>
try{
m_pRecordset->MoveFirst();
while(m_pRecordset->adoEOF==VARIANT_FALSE)
{
m_pRecordset->Fields->GetItem
(_variant_t("姓名"))->Value=_bstr_t("赵薇");
......
m_pRecordset->Update();

m_pRecordset->MoveNext();
}
}//try

  改变了Value属性的|x变了字段的倹{?BR>
  Ҏ二:

m_pRecordset->Fields->GetItem
(_variant_t("姓名"))->PutValue(_bstr_t("赵薇"));

  Ҏ三:是用定义绑定类的方法(详见后面的介l)?BR>
  6、添加记?BR>
  新记录添加成功后Q即自动成ؓ当前记录。AddNewҎ有两UŞ式,一个含有参敎ͼ而另一个则不带参数?BR>
  Ҏ一Q不带参敎ͼQ?BR>
// Add new record into this table:
try{
if(!m_pRecordset->Supports(adAddNew)) return;

m_pRecordset->AddNew();
m_pRecordset->Fields->GetItem
(_variant_t("姓名"))->Value=_bstr_t("赵薇");
m_pRecordset->Fields->GetItem
(_variant_t("性别"))->Value=_bstr_t("?);
m_pRecordset->Fields->GetItem
(_variant_t("age"))->Value=_variant_t((short)20);
m_pRecordset->Fields->GetItem
(_variant_t("marry"))->Value=_bstr_t("未婚");
m_pRecordset->Update();
}//try
catch (_com_error &e)
{
::MessageBox(NULL, "又出毛病了?,"提示",MB_OK ?MB_ICONWARNING);
}

  q种Ҏ弄完了还要调用Update()?BR>
  Ҏ二(带参敎ͼQ?BR>
_variant_t varName[4],narValue[4];
varName[0] = L"姓名";
varName[1] = L"性别";
varName[2] = L"age";
varName[3] = L"marry";
narValue[0]=_bstr_t("赵薇");
narValue[1]=_bstr_t("?);
narValue[2]=_variant_t((short)20);
narValue[3]=_bstr_t("未婚");

const int nCrit = sizeof varName / sizeof varName[0];
// Create SafeArray Bounds and initialize the array
SAFEARRAYBOUND rgsaName[1],rgsaValue[1];
rgsaName[0].lLbound = 0;
rgsaName[0].cElements = nCrit;
SAFEARRAY *psaName = SafeArrayCreate( VT_VARIANT, 1, rgsaName );
rgsaValue[0].lLbound = 0;
rgsaValue[0].cElements = nCrit;
SAFEARRAY *psaValue = SafeArrayCreate( VT_VARIANT, 1, rgsaValue );
// Set the values for each element of the array
HRESULT hr1=S_OK.hr2=S_OK;
for( long i = 0 ; i < nCrit && SUCCEEDED( hr1 ) && SUCCEEDED( hr2 );i++)
{
hr1=SafeArrayPutElement(psaName, &i,&varName[i]);
hr2=SafeArrayPutElement(psaValue, &i,&narValue[i]); }

// Initialize and fill the SafeArray
VARIANT vsaName,vsaValue;
vsaName.vt = VT_VARIANT ?VT_ARRAY;
vsaValue.vt = VT_VARIANT ?VT_ARRAY;
V_ARRAY(&vsaName) = psaName;//&vsaName->parray=psaName;
//see definition in oleauto.h file.
V_ARRAY(&vsaValue) = psaValue;

// Add a new record:
m_pRecordset->AddNew(vsaName,vsaValue);

  q种Ҏ不需要调用UpdateQ因为添加后QADO会自动调用它。此Ҏ主要是用SafeArray挺麻烦?BR>
  Ҏ三:是用定义绑定类的方法(详见后面的介l)?BR>
 7、删除记?BR>
  调用Recordset的DeleteҎp了,删除的是当前记录。要了解Delete的其它用法请查阅参考文献?BR>
try{
m_pRecordset->MoveFirst();
while(m_pRecordset->adoEOF==VARIANT_FALSE)
{
CString sName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem
(_variant_t("姓名"))->Value);
if(::MessageBox(NULL,"姓名="+sName+"\n删除她吗Q?,
"提示",MB_YESNO ?MB_ICONWARNING)==IDYES)
{
m_pRecordset->Delete(adAffectCurrent);
m_pRecordset->Update();
}
m_pRecordset->MoveNext();
}
}//try
catch (_com_error &e)
{
::MessageBox(NULL,"又出毛病了?,"提示",MB_OK ?MB_ICONWARNING);
}

  8、用带参数的命?BR>
  Command对象所代表的就是一个Provider能够理解的命令,如SQL语句{。用Command对象的关键就是把表示命o的语句设|到CommandText属性中Q然后调用Command对象的ExecuteҎp了。一般情况下在命令中无需使用参数Q但有时使用参数Q可以增加其灉|性和效率?BR>
  (1). 建立q接、命令对象和记录集对?BR>
  本例中表C命令的语句是一个SQL语句QSELECT语句Q。SELECT语句中的问号?׃表参敎ͼ如果要多个参敎ͼ多攑և个问P每个问号代表一个参数?BR>
_ConnectionPtr Conn1;
_CommandPtr Cmd1;
ParametersPtr *Params1 = NULL; // Not an instance of a smart pointer.
_ParameterPtr Param1;
_RecordsetPtr Rs1;

try
{
// Create Connection Object (1.5 Version)
Conn1.CreateInstance( __uuidof( Connection ) );
Conn1->ConnectionString = bstrConnect;
Conn1->Open( bstrEmpty, bstrEmpty, bstrEmpty, -1 );
// Create Command Object
Cmd1.CreateInstance( __uuidof( Command ) );
Cmd1->ActiveConnection = Conn1;
Cmd1->CommandText = _bstr_t("SELECT * FROM mytable WHERE age< ?");
}//try

  要注意命令对象必Mq接对象兌h才能起作用,本例中将命o对象的ActiveConnection属性设|ؓq接对象的指针,即ؓ此目的:

Cmd1->ActiveConnection = Conn1;

  (2). 创徏参数对象Qƈl参数赋?BR>
// Create Parameter Object
Param1 = Cmd1->CreateParameter( _bstr_t(bstrEmpty),
adInteger,
adParamInput,
-1,
_variant_t( (long) 5) );
Param1->Value = _variant_t( (long) 5 );
Cmd1->Parameters->Append( Param1 );

  用命令对象的Ҏ来创Z个参数对象,其中的长度参敎ͼW三个)如果是固定长度的cdQ就?1Q如果是字符串等可变长度的就填其实际长度。Parameters是命令对象的一个容器,它的AppendҎ是把创建的参数对象q加到该容器里。Appendq去的参数按先后序与SQL语句中的问号从左臛_一一对应?BR>
  (3). 执行命o打开记录?BR>
// Open Recordset Object
Rs1 = Cmd1->Execute( &vtEmpty, &vtEmpty2, adCmdText );

  但要注意Q用Command和Connection对象的ExecuteҎ得到的Recordset是只ȝ。因为在打开Recordset之前Q我们无法设|它的LockType属性(光认gؓ只读Q。而在打开之后讄LockType不v作用?BR>
  我发现用上述Ҏ得到记录集Rs1后,不但Rs1中的记录无法修改Q即使直接用SQL语句修改同一表中M记录都不行?BR>
  要想能修Ҏ据,q是要用Recordset自己的OpenҎ才行Q如Q?BR>
try{
m_pRecordset->Open((IDispatch *) Cmd1, vtMissing,
adOpenStatic, adLockOptimistic, adCmdUnspecified);
}
catch (_com_error &e)
{
::MessageBox(NULL,"mytable表不存在?,"提示",MB_OK ?MB_ICONWARNING);
}

  Recordset对象的OpenҎ真是太好了,其第一个参数可以是SQL语句、表名字、命令对象指针等{?BR>
  9、响应ADO的通知事g

  通知事g是当某个特定事件发生时Q由Provider通知客户E序Q换句话_是由Provider调用客户E序中的一个特定的ҎQ即事g的处理函敎ͼ。所以ؓ了响应一个事Ӟ最关键的就是要实现事g的处理函数?BR>
  (1). 从ConnectionEventsVt接口zZ个类

  Z响应_Connection的通知事gQ应该从ConnectionEventsVt接口zZ个类Q?BR>
class CConnEvent : public ConnectionEventsVt
{
private:
ULONG m_cRef;
public:
CConnEvent() { m_cRef = 0; };
~CConnEvent() {};

STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
STDMETHODIMP raw_InfoMessage(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection);
STDMETHODIMP raw_BeginTransComplete(
LONG TransactionLevel,
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection);
......
};

   (2). 实现每一个事件的处理函数(凡是带raw_前缀的方法都把它实现?Q?BR>
STDMETHODIMP CConnEvent::raw_InfoMessage(
struct Error *pError,
EventStatusEnum *adStatus,
struct _Connection *pConnection)
{
*adStatus = adStatusUnwantedEvent;
return S_OK;
};

  有些Ҏ虽然你ƈ不需要,但也必须实现它,只需单地q回一个S_OK卛_。但如果要避免经常被调用Q还应在其中adStatus参数讄为adStatusUnwantedEventQ则在本ơ调用后Q以后就不会被调用了?BR>另外q必d现QueryInterface, AddRef, 和Release三个Ҏ:

STDMETHODIMP CConnEvent::QueryInterface(REFIID riid, void ** ppv)
{
*ppv = NULL;
if (riid == __uuidof(IUnknown) ││
riid == __uuidof(ConnectionEventsVt)) *ppv = this;
if (*ppv == NULL)
return ResultFromScode(E_NOINTERFACE);
AddRef();
return NOERROR;
}
STDMETHODIMP_(ULONG) CConnEvent::AddRef() { return ++m_cRef; };
STDMETHODIMP_(ULONG) CConnEvent::Release()
{
if (0 != --m_cRef) return m_cRef;
delete this;
return 0;
}

  (3). 开始响应通知事g

// Start using the Connection events
IConnectionPointContainer *pCPC = NULL;
IConnectionPoint *pCP = NULL;

hr = pConn.CreateInstance(__uuidof(Connection));
if (FAILED(hr)) return;

hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer),
(void **)&pCPC);
if (FAILED(hr)) return;
hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);
pCPC->Release();
if (FAILED(hr)) return;

pConnEvent = new CConnEvent();
hr = pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);
if (FAILED(hr)) return rc;
hr = pCP->Advise(pUnk, &dwConnEvt);
pCP->Release();
if (FAILED(hr)) return;

pConn->Open("dsn=Pubs;", "sa", "", adConnectUnspecified);

  也就是说在连?Open)之前做q些事?BR>
  (4). 停止响应通知事g

pConn->Close();
// Stop using the Connection events
hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer),
(void **) &pCPC);
if (FAILED(hr)) return;
hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);
pCPC->Release();
if (FAILED(hr)) return rc;
hr = pCP->Unadvise( dwConnEvt );
pCP->Release();
if (FAILED(hr)) return;

  在连接关闭之后做qg事?


]]>
_variant_t 到 CString 转换http://www.shnenglu.com/ivenher/articles/2289.html爱饭?/dc:creator>爱饭?/author>Fri, 30 Dec 2005 08:45:00 GMThttp://www.shnenglu.com/ivenher/articles/2289.htmlhttp://www.shnenglu.com/ivenher/comments/2289.htmlhttp://www.shnenglu.com/ivenher/articles/2289.html#Feedback3http://www.shnenglu.com/ivenher/comments/commentRss/2289.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/2289.html数据cd转换函数

CString CZjyDlg::VariantToString(VARIANT var)

{

CString strValue;

         _variant_t var_t;

         _bstr_t bstr_t;

         time_t cur_time;

         CTime time_value;

         COleCurrency var_currency;

         switch(var.vt)

         {

         case VT_EMPTY:

         case VT_NULL:strValue=_T("");break;

         case VT_UI1:strValue.Format("%d",var.bVal);break;

         case VT_I2:strValue.Format("%d",var.iVal);break;

         case VT_I4:strValue.Format("%d",var.lVal);break;

         case VT_R4:strValue.Format("%f",var.fltVal);break;

         case VT_R8:strValue.Format("%f",var.dblVal);break;

         case VT_CY:

                   var_currency=var;

                   strValue=var_currency.Format(0);break;

         case VT_BSTR:

                   var_t =var;

                   bstr_t=var_t;

                   strValue.Format("%s",(const char *)bstr_t);break;

         case VT_DATE:

                   cur_time=var.date;

                   time_value=cur_time;

                   strValue.Format("%A,%B,%d,%Y");break;

         case VT_BOOL:strValue.Format("%d",var.boolVal);break;

         default:strValue=_T("");break;

         }

         return strValue;

}



]]>
ado 出错处理http://www.shnenglu.com/ivenher/articles/2150.html爱饭?/dc:creator>爱饭?/author>Mon, 26 Dec 2005 12:13:00 GMThttp://www.shnenglu.com/ivenher/articles/2150.htmlhttp://www.shnenglu.com/ivenher/comments/2150.htmlhttp://www.shnenglu.com/ivenher/articles/2150.html#Feedback2http://www.shnenglu.com/ivenher/comments/commentRss/2150.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/2150.html3127——没有找到目标表
3092——目标表已经存在
例如Q?BR>catch(const _com_error e)
{
     AfxMessageBox(e.Description());
     long errorCode=e.WCode();
     if(3127==errorCode) AfxMessageBox("表不存在");
     if(3092==errorCode) AfxMessageBox("表已l存?);
     return FALSE;



]]>
用ADO操作数据库的Ҏ步骤http://www.shnenglu.com/ivenher/articles/2149.html爱饭?/dc:creator>爱饭?/author>Mon, 26 Dec 2005 11:37:00 GMThttp://www.shnenglu.com/ivenher/articles/2149.htmlhttp://www.shnenglu.com/ivenher/comments/2149.htmlhttp://www.shnenglu.com/ivenher/articles/2149.html#Feedback0http://www.shnenglu.com/ivenher/comments/commentRss/2149.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/2149.html        
/***********************ADO接口?***********************************/
ADO库包含三个基本接?_ConnectionPtr接口、_CommandPtr接口和_RecordsetPtr接口?

_ConnectionPtr接口q回一个记录集或一个空指针?BR>通常使用它来创徏一个数据连接或执行一条不q回Ml果的SQL语句Q如一个存储过E?BR>使用_ConnectionPtr接口q回一个记录集不是一个好的用方法?BR>通常同Cdatabase一P使用它创Z个数据连接,然后使用其它对象执行数据输入输出操作?BR>
_CommandPtr接口q回一个记录集?BR>它提供了一U简单的Ҏ来执行返回记录集的存储过E和SQL语句?BR>在用_CommandPtr接口Ӟ你可以利用全局_ConnectionPtr接口Q也可以在_CommandPtr接口里直接用连接串?BR>如果你只执行一ơ或几次数据讉K操作Q后者是比较好的选择?BR>但如果你要频J访问数据库Qƈ要返回很多记录集Q那么,你应该用全局_ConnectionPtr接口创徏一个数据连接,
然后使用_CommandPtr接口执行存储q程和SQL语句?BR>

_RecordsetPtr是一个记录集对象?BR>与以上两U对象相比,它对记录集提供了更多的控制功能,如记录锁定,游标控制{?BR>。同_CommandPtr接口一P它不一定要使用一个已l创建的数据q接Q?BR>可以用一个连接串代替q接指针赋给_RecordsetPtr的connection成员变量Q让它自己创建数据连接?BR>如果你要使用多个记录集,最好的Ҏ是同Command对象一样用已l创Z数据q接的全局_ConnectionPtr接口
Q然后用_RecordsetPtr执行存储q程和SQL语句?BR>

/***********************基本程***********************************/
(1)初始化COM库,引入ADO库定义文?BR>(2)用Connection对象q接数据?BR>(3)利用建立好的q接Q通过Connection、Command对象执行SQL命oQ或利用Recordset对象取得l果?BR>   录集q行查询、处理?BR>(4)使用完毕后关闭连接释攑֯象?BR>


/***********************?】COM库的初始?**********************************/
我们可以使用AfxOleInit()来初始化COM库,q项工作通常在CWinApp::InitInstance()的重载函C?BR>成,L如下代码:

BOOL CADOTest1App::InitInstance()
{
  AfxOleInit();
  ......
}


/*****************?】用#import指o引入ADOcd?*********************/
我们在stdafx.h中加入如下语句:
#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
其最l作用同我们熟悉?includecM,~译的时候系l会为我们生成msado15.tlh,ado15.tli两个C++头文件来定义ADO库?BR>


/***************?】创建Connection对象q连接数据库********************/

首先我们需要添加一个指向Connection对象的指?

_ConnectionPtr m_pConnection;

BOOL CADOTest1Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
try
{
  HRESULT hr = m_pConnection.CreateInstance("ADODB.Connection");//创徏Connection对象
  if(SUCCEEDED(hr))
  {
   hr = m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=test.mdb","","",adModeUnknown);//q接数据?BR>   //上面一句中q接字串中的Provider是针对ACCESS2000环境的,对于ACCESS97,需要改?Provider=Microsoft.Jet.OLEDB.3.51;  }
  }
}
catch (_com_error e) //COM错误取得,当执行COM功能的时候,如果出错Q可以捕捉到_com_error的异?BR>{  
  CString strComError;
  strComError.Format("错误~号: %08lx\n错误信息: %s\n错误? %s\n错误描述: %s",
       e.Error(),                  // 错误~号
       e.ErrorMessage(),           // 错误信息
       (LPCSTR) e.Source(),        // 错误?BR>       (LPCSTR) e.Description());  // 错误描述
      
  
  ::MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION);
}
}
也可以用UDL文gq行q接?BR>try
{  
m_pConnection.CreateInstance(__uuidof(Connection));  
m_pConnection->ConnectionString ="File Name=e.udl";
m_pConnection->Open("","","",NULL);
}
catch(_com_error e)
{....}

◆在q段代码中我们是通过Connection对象的OpenҎ来进行连接数据库的,下面是该Ҏ的原?BR>
HRESULT Connection15::Open (_bstr_t ConnectionString, _bstr_t UserID, _bstr_t Password, long Options )

ConnectionString 接字?
UserID    是用户名,
Password   是登陆密?
Options    是连接选项,用于指定Connection对象Ҏ据的更新许可?
     Options可以是如下几个常?

  adModeUnknown:   ~省。当前的许可权未讄
  adModeRead:    只读
  adModeWrite:   只写
  adModeReadWrite:  可以d
  adModeShareDenyRead: L其它Connection对象以读权限打开q接
  adModeShareDenyWrite: L其它Connection对象以写权限打开q接
  adModeShareExclusive: L其它Connection对象打开q接
  adModeShareDenyNone: 允许其它E序或对象以M权限建立q接


◆常用的数据库连接方法:

(1)通过JET数据库引擎对ACCESS2000数据库的q接
m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\test.mdb","","",adModeUnknown);

(2)通过DSN数据源对M支持ODBC的数据库q行q接:
m_pConnection->Open("Data Source=adotest;UID=sa;PWD=;","","",adModeUnknown);
//m_pConnection->Open("DSN=test;","","",0);   //q接叫作test的ODBC数据?

(3)不通过DSN对SQL SERVER数据库进行连接:
m_pConnection->Open("driver={SQL Server};Server=127.0.0.1;DATABASE=vckbase;UID=sa;PWD=139","","",adModeUnknown);
其中Server是SQL服务器的名称QDATABASE是库的名U?BR>
◆先介绍Connection对象中两个有用的属性ConnectionTimeOut与State
ConnectionTimeOut用来讄q接的超时时_需要在Open之前调用Q例?
  m_pConnection->ConnectionTimeout = 5; //讄时旉?U?BR>  m_pConnection->Open("Data Source=adotest;","","",adModeUnknown);

State属性指明当前Connection对象的状态,0表示关闭Q?表示已经打开Q我们可以通过
dq个属性来作相应的处理Q例?
if(m_pConnection->State)
  m_pConnection->Close(); //如果已经打开了连接则关闭?BR>



4?*****************执行SQL命oq取得结果记录集****************/

Z取得l果记录集,我们定义一个指向Recordset对象的指?
        _RecordsetPtr m_pRecordset;
qؓ其创建Recordset对象的实?  
        m_pRecordset.CreateInstance("ADODB.Recordset");

SQL命o的执行可以采用多UŞ式,下面我们一q行阐述?BR>
?1)利用Connection对象的ExecuteҎ执行SQL命o
ExecuteҎ的原型如下所C?

_RecordsetPtr Connection15::Execute (_bstr_t CommandText, VARIANT * RecordsAffected, long Options )
其中
  CommandText   是命令字Ԍ通常是SQL命o?BR>  RecordsAffected  是操作完成后所影响的行?
  Options    表示CommandText中内容的cdQOptions可以取如下g一Q?BR>       adCmdText:  表明CommandText是文本命?BR>       adCmdTable:  表明CommandText是一个表?BR>       adCmdProc:  表明CommandText是一个存储过E?BR>       adCmdUnknown: 未知

Execute执行完后q回一个指向记录集的指针,下面我们l出具体代码q作说明?nbsp; 
try
{
_variant_t ra;

m_pConnection->Execute("CREATE TABLE 学生信息(学号 INTEGER,姓名 TEXT,q龄 INTEGER,生日 DATETIME)",&ra,adCmdText);
m_pConnection->Execute("INSERT INTO 学生信息(学号,姓名,q龄,生日) VALUES (112105, 'E红U',22,'1982-08-16')",&ra,adCmdText);//往表格里面d记录
m_pRecordset = m_pConnection->Execute("SELECT COUNT(*) FROM 学生信息",&ra,adCmdText);   //执行SQLl计命o得到包含记录条数的记录集

_variant_t vCount = m_pRecordset->GetCollect((_variant_t)(long)(0)); //取得W一个字D늚值放入vCount变量

m_pRecordset->Close();
CString message;
message.Format("共有%d条记?,vCount.lVal);
AfxMessageBox(message);  
}

catch (_com_error e)
{ ...}



?2)利用 Command对象 来执行SQL命o
try
{
  _CommandPtr m_pCommand;
  m_pCommand.CreateInstance("ADODB.Command");
  
  m_pCommand->ActiveConnection = m_pConnection; //关键的一句,徏立的q接赋值给?BR>
  m_pCommand->CommandText="INSERT INTO 学生信息(学号,姓名,q龄,生日) VALUES (112105, 'E红U',22,'1982-08-16')";
  m_pCommand->Execute(NULL,NULL,adCmdText);

  m_pCommand->CommandText="SELECT COUNT(*) FROM 学生信息";
  m_pRecordset=m_pCommand->Execute(NULL,NULL,adCmdText);

  _variant_t vCount = m_pRecordset->GetCollect((_variant_t)(long)0); //取得W一个字D늚?BR>  
  CString str;
  str.Format("共有%d条记?,vCount.lVal);
  AfxMessageBox(str);  

  m_pRecordset->Close();

}
catch (_com_error e) {...}

在这D代码中我们只是用Command对象来执行了SELECT查询语句Q?BR>Command对象在进行存储过E的调用中能真正体现它的作用。下ơ我们将详细介绍?


?3)直接用Recordset对象q行查询取得记录?
例如
  m_pRecordset->Open("SELECT * FROM 学生信息",_variant_t((IDispatch *)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);

OpenҎ的原型是q样?
HRESULT Recordset15::Open ( const _variant_t & Source, const _variant_t & ActiveConnection, enum CursorTypeEnum CursorType, enum LockTypeEnum LockType, long Options )
其中Q?BR>①Source是数据查询字W串
②ActiveConnection是已l徏立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象)
③CursorType光标cdQ它可以是以下g一,Lq个枚Dl构:
   enum CursorTypeEnum
   {
    adOpenUnspecified = -1, //不作特别指定
    adOpenForwardOnly = 0, //前滚静态光标。这U光标只能向前浏览记录集Q比如用MoveNext向前滚动,q种方式可以提高览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能?BR>    adOpenKeyset = 1,  //采用q种光标的记录集看不到其它用L新增、删除操作,但对于更新原有记录的操作对你是可见的?BR>    adOpenDynamic = 2,  //动态光标。所有数据库的操作都会立卛_各用戯录集上反应出来?BR>    adOpenStatic = 3  //静态光标。它Z的记录集产生一个静态备份,但其它用L新增、删除、更新操作对你的记录集来说是不可见的?BR>   };
④LockType锁定cdQ它可以是以下g一Q请看如下枚丄构:
   enum LockTypeEnum
   {
    adLockUnspecified = -1,  //未指?BR>    adLockReadOnly = 1,   //只读记录?BR>    adLockPessimistic = 2,  //悲观锁定方式。数据在更新旉定其它所有动作,q是最安全的锁定机?BR>    adLockOptimistic = 3,  //乐观锁定方式。只有在你调用UpdateҎ时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
    adLockBatchOptimistic = 4Q?//乐观分批更新。编辑时记录不会锁定Q更攏V插入及删除是在批处理模式下完成?BR>   };
⑤Options请参考本文中对Connection对象的ExecuteҎ的介l?BR>



/***********************?】记录集的遍历、更?************************/

Ҏ我们刚才通过执行SQL命o建立好的 学生信息 表,它包含四个字D?学号Q姓名,q龄Q生?BR>以下的代码实玎ͼ打开记录集,遍历所有记录,删除W一条记录,d三条记录Q移动光标到W二?BR>记录Q更改其q龄Q保存到数据库?BR>
try
{
  _variant_t vUsername,vBirthday,vID,vOld;
  _RecordsetPtr m_pRecordset;
  
  m_pRecordset.CreateInstance("ADODB.Recordset");
  m_pRecordset->Open("SELECT * FROM 学生信息",_variant_t((IDispatch*)m_pConnection,true),adOpenStatic,adLockOptimistic,adCmdText);
  
  while(!m_pRecordset->adoEOF)
  {
   vID = m_pRecordset->GetCollect(_variant_t((long)0));    //取得W?列的??开始计敎ͼ你也可以直接l出列的名称Q如下一?BR>   vUsername = m_pRecordset->GetCollect("姓名");  //取得姓名字段的?BR>   vOld = m_pRecordset->GetCollect("q龄");
   vBirthday = m_pRecordset->GetCollect("生日");
  
   TRACE("id:%d,姓名:%s,q龄:%d,生日:%s\r\n",
    vID.lVal,
    (LPCTSTR)(_bstr_t)vUsername,
    vOld.lVal,
    (LPCTSTR)(_bstr_t)vBirthday);  //在DEBUG方式下的OUTPUTH口输出记录集中的记?BR>
   m_pRecordset->MoveNext();    //Ud下一条记?BR>  }
  
  m_pRecordset->MoveFirst();    //Ud首条记录
  m_pRecordset->Delete(adAffectCurrent);    //删除当前记录
  
  
  for(int i=0;i<3;i++)    //d三条新记录ƈ赋?BR>  {
   m_pRecordset->AddNew();    //d新记?BR>   m_pRecordset->PutCollect("学号",_variant_t((long)(i+10)));
   m_pRecordset->PutCollect("姓名",_variant_t("王斌q?));
   m_pRecordset->PutCollect("q龄",_variant_t((long)21));
   m_pRecordset->PutCollect("生日",_variant_t("1930-3-15"));
  }
  
  m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));    //从第一条记录往下移动一条记?即移动到W二条记录处
  m_pRecordset->PutCollect(_variant_t("q龄"),_variant_t((long)45));    //修改其年?BR>  m_pRecordset->Update();    //保存到库?BR>  
} catch (_com_error e){}



/***********************?】关闭记录集与连?*************************/
记录集或q接都可以用CloseҎ来关?nbsp;     
m_pRecordset->Close(); //关闭记录?nbsp; 
m_pConnection->Close(); //关闭q接




在stdafx.h中进行宏定义:
#if !defined CATCH_ERROR
#define CATCH_ERROR           \
  {             \
   CString strComError;       \
   strComError.Format("错误~号: %08lx\n错误信息: %s\n错误? %s\n错误描述: %s", \
        e.Error(),                  \
        e.ErrorMessage(),           \
        (LPCSTR) e.Source(),        \
        (LPCSTR) e.Description());  \
   ::MessageBox(NULL,strComError,"错误",MB_ICONEXCLAMATION); \
  }
#endif
使用ҎQ?BR>try
{  ...}
catch(_com_error e)
{
CATCH_ERROR;
}


]]>
ADO数据库编E入?/title><link>http://www.shnenglu.com/ivenher/articles/1773.html</link><dc:creator>爱饭?/dc:creator><author>爱饭?/author><pubDate>Thu, 15 Dec 2005 03:03:00 GMT</pubDate><guid>http://www.shnenglu.com/ivenher/articles/1773.html</guid><wfw:comment>http://www.shnenglu.com/ivenher/comments/1773.html</wfw:comment><comments>http://www.shnenglu.com/ivenher/articles/1773.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ivenher/comments/commentRss/1773.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ivenher/services/trackbacks/1773.html</trackback:ping><description><![CDATA[ADO 是目前在Windows环境中比较流行的客户端数据库~程技术。ADO是徏立在OLE DB底层技术之上的高~程接口Q因而它兼具有强大的数据处理功能Q处理各U不同类型的数据源、分布式的数据处理等{)和极其简单、易用的~程接口Q因而得Cq泛的应用。而且按微软公司的意图QOLE DB和ADO逐步取代 ODBC和DAO。现在介lADO各种应用的文章和书籍有很多,本文着重站在初学者的角度Q简要探讨一下在VC++中用ADO~程时的一些问题。我们希望阅L文之前,您对ADO技术的基本原理有一些了解?BR>一、在VC++中用ADO~程<BR>ADO实际上就是由一lAutomation对象构成的组Ӟ因此可以象用其它Q何Automation对象一样用ADO。ADO中最重要的对象有三个QConnection、Command和RecordsetQ它们分别表C接对象、命令对象和记录集对象。如果您熟悉使用MFC中的ODBCc(CDatabase、CRecordset)~程Q那么学习ADO~程十分容易了?BR>使用ADO~程时可以采用以下三U方法之一Q?BR>1、用预处理指o#import<BR>#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \<BR>   no_namespace rename("EOF", "EndOfFile")<BR>但要注意不能攑֜stdAfx.h文g的开_而应该放在所有include指o的后面。否则在~译时会出错?BR>E序在编译过E中QVC++会读出msado15.dll中的cd库信息,自动产生两个该类型库的头文g和实现文件msado15.tlh和msado15.tliQ在您的Debug或Release目录下)。在q两个文仉定义了ADO的所有对象和ҎQ以及一些枚丑֞的常量等。我们的E序只要直接调用q些Ҏp了,与用MFC中的COleDispatchDriverc调用Automation对象十分cM?BR>2、用MFC中的CIDispatchDriver<BR>是通过dmsado15.dll中的cd库信息,建立一个COleDispatchDrivercȝzc,然后通过它调用ADO对象?BR>3、直接用COM提供的API<BR> 如用如下代码:<BR> CLSID clsid;<BR> HRESULT hr = ::CLSIDFromProgID(L"ADODB.Connection", &clsid);<BR> if(FAILED(hr))<BR> {...}<BR> ::CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IDispatch, (void **)<BR>      &pDispatch);<BR> if(FAILED(hr))<BR> {...}<BR>以上三种ҎQ第一和第二种cMQ可能第一U好用一些,W三U编E可能最ȝ。但可能W三U方法也是效率最高的Q程序的寸也最,q且对ADO的控制能力也最强?BR>据微软资料介l,W一U方法不支持Ҏ调用中的默认参数Q当然第二种Ҏ也是q样Q但W三U就不是q样了。采用第三种Ҏ的水q也最高。当你需要绕qADO而直接调用OLE DB底层的方法时Q就一定要使用W三U方法了?BR>ADO~程的关键,是熟练地运用ADO提供的各U对?object)、方?method)、属?property)和容器(collectionQ。另外,如果是在MS SQL或Oracle{大型数据库上编E,q要能熟l用SQL语言?BR>二、?importҎ的编E步?BR>q里您?import的方法,因ؓ它易学、易用,代码也比较简z?BR>1?d#import指o<BR>打开stdafx.h文gQ将下列内容d到所有的include指o之后Q?BR>#include <icrsint.h>   //Include support for VC++ Extensions<BR>#import "C:\Program Files\Common Files\System\ADO\msado15.dll" \<BR>   no_namespace rename("EOF", "adoEOF")<BR>其中icrsint.h文g包含了VC++扩展的一些预处理指o、宏{的定义Q用于COM~程时用?BR>2、定义_ConnectionPtr型变量,q徏立数据库q接<BR>建立了与数据库服务器的连接后Q才能进行其他有x据库的访问和操作。ADO使用Connection对象来徏立与数据库服务器的连接,所以它相当于MFC中的CDatabasecR和CDatabasecMP调用Connection对象的OpenҎ卛_建立与服务器的连接?BR>数据cd _ConnectionPtr实际上就是由cL板_com_ptr_t而得到的一个具体的实例c,其定义可以到msado15.tlh、comdef.h 和comip.hq三个文件中扑ֈ。在msado15.tlh中有Q?BR>_COM_SMARTPTR_TYPEDEF(_Collection, __uuidof(_Collection));<BR>l宏扩展后就得到了_ConnectionPtrcR_ConnectionPtrcd装了Connection对象的Idispatch接口指针Q及一些必要的操作。我们就是通过q个指针来操UConnection对象。类似地Q后面用到的_CommandPtr和_RecordsetPtrcd也是q样得到的,它们分别表示命o对象指针和记录集对象的指针?BR>Q?Q、连接到MS SQL Server<BR>注意q接字符串的格式Q提供正的q接字符串是成功q接到数据库服务器的W一步,有关q接字符串的详细信息参见微YMSDN Library光盘?BR>本例q接字符串中的server_nameQdatabase_nameQuser_name和password在编E时都应该替换成实际的内宏V?BR> _ConnectionPtr pMyConnect=NULL;<BR> HRESULT hr=pMyConnect.CreateInstance(__uuidof(Connection)));<BR> if(FAILED(hr))return;<BR>_bstr_t strConnect="Provider=SQLOLEDB; Server=server_name;"<BR>  "Database=database_name; uid=user_name; pwd=password;"; <BR>//connecting to the database server now:<BR> try{pMyConnect->Open(strConnect,"","",NULL);}<BR> catch (_com_error &e)<BR> {<BR>  ::MessageBox(NULL,e.Description(),"警告",MB_OK | MB_ICONWARNING);<BR> }<BR><BR>注意Connection对象的OpenҎ中的q接字符串参数必LBSTR或_bstr_tcd。另外,本例是直接通过OLE DB Provider建立q接Q所以无需建立数据源?BR>Q?Q、通过ODBC Driverq接到Database Server<BR>q接字符串格式与直接用ODBC~程时的差不多:<BR>_bstr_t strConnect="DSN=datasource_name; Database=database_name; uid=user_name; pwd=password;";<BR>此时与ODBC~程一P必须先徏立数据源?BR>3、定义_RecordsetPtr型变量,q打开数据?BR>定义_RecordsetPtr型变量,然后通过它调用Recordset对象的OpenҎQ即可打开一个数据集。所以Recordset对象与MFC中的CRecordsetcȝ|它也有当前记录、当前记录指针的概念。如Q?BR> _RecordsetPtr m_pRecordset;<BR> if(!FAILED(m_pRecordset.CreateInstance( __uuidof( Recordset )))<BR> {<BR>  m_pDoc->m_initialized=FALSE;<BR>  return;<BR> }<BR>try{<BR>  m_pRecordset->Open(_variant_t("mytable"),<BR>            _variant_t((IDispatch *)pMyConnect,true), adOpenKeyset,<BR>            adLockOptimistic, adCmdTable);<BR> }<BR> catch (_com_error &e)<BR> {<BR>  ::MessageBox(NULL,"无法打开mytable表?,"提示",<BR>MB_OK | MB_ICONWARNING);<BR> }<BR>Recordset对象的OpenҎ非常重要Q它的第一个参数可以是一个SQL语句、一个表的名字或一个命令对象等{;W二个参数就是前面徏立的q接对象的指针。此外,用Connection和Command对象的ExecuteҎ也能得到记录集,但是只读的?BR>4、读取当前记录的数据<BR>我认取数据的最方便的方法如下:<BR> try{<BR>  m_pRecordset->MoveFirst();   <BR>  while(m_pRecordset->adoEOF==VARIANT_FALSE) <BR>  {<BR>   //Retrieve column's value: <BR>   CString sName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem<BR>    (_variant_t("name"))->Value);<BR>   short cAge=(short)(m_pRecordset->Fields->GetItem<BR>    (_variant_t("age"))->Value);<BR>   //Do something what you want to do:<BR>   ......<BR>   m_pRecordset->MoveNext();   <BR>  }<BR> }//try<BR> catch (_com_error &e)<BR> {<BR>  CString str=(char*)e.Description();<BR>  ::MessageBox(NULL,str+"\n又出毛病了?,"提示",<BR>MB_OK | MB_ICONWARNING);<BR> }<BR> <P>本例中的name和age都是字段名,d的字D值分别保存在sName和cAge变量内。例中的Fields是Recordset对象的容器,GetItemҎq回的是Field对象Q而Value则是Field对象的一个属性(卌字段的|。通过此例Q应掌握操纵对象属性的Ҏ。例如,要获得Field 对象的Value属性的值可以直接用属性名Value来引用它Q如上例Q,但也可以调用GetҎQ例如:<BR>CString sName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem<BR>    (_variant_t("name"))->GetValue());<BR>从此例还可以看到Q判断是否到达记录集的末,使用记录集的adoEOF属性,其D为真卛_了结,反之则未到。判断是否到达记录集开_则可用BOF属性?BR>另外Q读取数据还有一个方法,是定义一个绑定的c,然后通过l定的变量得到字D|详见后面的介l)?BR>5、修Ҏ?BR>Ҏ一Q?BR> try{<BR>  m_pRecordset->MoveFirst();   <BR>  while(m_pRecordset->adoEOF==VARIANT_FALSE) <BR>  {   <BR>   m_pRecordset->Fields->GetItem<BR>    (_variant_t("姓名"))->Value=_bstr_t("赵薇");<BR>   ......<BR>   m_pRecordset->Update();<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>   m_pRecordset->MoveNext();   <BR>  }<BR> }//try<BR>改变了Value属性的|x变了字段的倹{?BR>Ҏ二:<BR>  m_pRecordset->Fields->GetItem<BR>    (_variant_t("姓名"))->PutValue(_bstr_t("赵薇"));<BR>Ҏ三:是用定义绑定类的方法(详见后面的介l)?BR>6、添加记?BR>新记录添加成功后Q即自动成ؓ当前记录。AddNewҎ有两UŞ式,一个含有参敎ͼ而另一个则不带参数?BR>Ҏ一Q不带参敎ͼQ?BR> // Add new record into this table:<BR> try{<BR>  if(!m_pRecordset->Supports(adAddNew)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>  m_pRecordset->AddNew(); <BR>  m_pRecordset->Fields->GetItem<BR>   (_variant_t("姓名"))->Value=_bstr_t("赵薇");<BR>  m_pRecordset->Fields->GetItem<BR>   (_variant_t("性别"))->Value=_bstr_t("?);<BR>  m_pRecordset->Fields->GetItem<BR>   (_variant_t("age"))->Value=_variant_t((short)20);<BR>  m_pRecordset->Fields->GetItem<BR>   (_variant_t("marry"))->Value=_bstr_t("未婚");<BR>  m_pRecordset->Update();  <BR> }//try<BR> catch (_com_error &e)<BR> {<BR>  ::MessageBox(NULL, "又出毛病了?,"提示",MB_OK | MB_ICONWARNING);<BR> }<BR>q种Ҏ弄完了还要调用Update()?BR>Ҏ二(带参敎ͼQ?BR>  _variant_t varName[4],narValue[4];<BR>  varName[0] = L"姓名";<BR>  varName[1] = L"性别";<BR>  varName[2] = L"age";<BR>  varName[3] = L"marry";<BR>  narValue[0]=_bstr_t("赵薇");<BR>  narValue[1]=_bstr_t("?);<BR>  narValue[2]=_variant_t((short)20);<BR>  narValue[3]=_bstr_t("未婚");<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>  const int nCrit = sizeof varName / sizeof varName[0];<BR>  // Create SafeArray Bounds and initialize the array<BR>  SAFEARRAYBOUND rgsaName[1],rgsaValue[1];<BR>  rgsaName[0].lLbound = 0;   <BR>  rgsaName[0].cElements = nCrit;<BR>  SAFEARRAY *psaName = SafeArrayCreate( VT_VARIANT, 1, rgsaName );<BR>  rgsaValue[0].lLbound = 0;<BR>  rgsaValue[0].cElements = nCrit;<BR>  SAFEARRAY *psaValue = SafeArrayCreate( VT_VARIANT, 1, rgsaValue );<BR>  // Set the values for each element of the array<BR>  HRESULT hr1=S_OK.hr2=S_OK;<BR>  for( long i = 0 ; i < nCrit && SUCCEEDED( hr1 ) && SUCCEEDED( hr2 );i++)   <BR>  {      <BR>   hr1=SafeArrayPutElement(psaName, &i,&varName[i]);<BR>   hr2=SafeArrayPutElement(psaValue, &i,&narValue[i]);       }<BR>   <BR>  // Initialize and fill the SafeArray<BR>  VARIANT vsaName,vsaValue;   <BR>  vsaName.vt = VT_VARIANT | VT_ARRAY;<BR>  vsaValue.vt = VT_VARIANT | VT_ARRAY;<BR>  V_ARRAY(&vsaName) = psaName;//&vsaName->parray=psaName;<BR>   //see definition in oleauto.h file.<BR>  V_ARRAY(&vsaValue) = psaValue;<BR>   <BR>  // Add a new record:<BR>  m_pRecordset->AddNew(vsaName,vsaValue);<BR>q种Ҏ不需要调用UpdateQ因为添加后QADO会自动调用它。此Ҏ主要是用SafeArray挺麻烦?BR>Ҏ三:是用定义绑定类的方法(详见后面的介l)?BR>7、删除记?BR>调用Recordset的DeleteҎp了,删除的是当前记录。要了解Delete的其它用法请查阅参考文献?BR> try{<BR>  m_pRecordset->MoveFirst();   <BR>  while(m_pRecordset->adoEOF==VARIANT_FALSE) <BR>  {<BR>   CString sName=(char*)(_bstr_t)(m_pRecordset->Fields->GetItem<BR>    (_variant_t("姓名"))->Value);<BR>   if(::MessageBox(NULL,"姓名="+sName+"\n删除她吗Q?,<BR>    "提示",MB_YESNO | MB_ICONWARNING)==IDYES)<BR>   {<BR>    m_pRecordset->Delete(adAffectCurrent);   <BR>    m_pRecordset->Update();<BR>   }<BR>   m_pRecordset->MoveNext();   <BR>  }<BR> }//try<BR> catch (_com_error &e)<BR> {<BR>  ::MessageBox(NULL,"又出毛病了?,"提示",MB_OK | MB_ICONWARNING);<BR> }<BR>8、用带参数的命?BR>Command对象所代表的就是一个Provider能够理解的命令,如SQL语句{。用Command对象的关键就是把表示命o的语句设|到CommandText属性中Q然后调用Command对象的ExecuteҎp了。一般情况下在命令中无需使用参数Q但有时使用参数Q可以增加其灉|性和效率?BR>(1). 建立q接、命令对象和记录集对?BR>本例中表C命令的语句是一个SQL语句QSELECT语句Q。SELECT语句中的问号?׃表参敎ͼ如果要多个参敎ͼ多攑և个问P每个问号代表一个参数?BR>_ConnectionPtr  Conn1;<BR>_CommandPtr     Cmd1;<BR>ParametersPtr   *Params1 = NULL;   // Not an instance of a smart pointer.<BR>_ParameterPtr   Param1;<BR>_RecordsetPtr   Rs1;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>try<BR>{<BR> // Create Connection Object (1.5 Version)<BR> Conn1.CreateInstance( __uuidof( Connection ) );<BR> Conn1->ConnectionString = bstrConnect;<BR>    Conn1->Open( bstrEmpty, bstrEmpty, bstrEmpty, -1 );<BR>    // Create Command Object<BR>    Cmd1.CreateInstance( __uuidof( Command ) );<BR>    Cmd1->ActiveConnection = Conn1;<BR>    Cmd1->CommandText  = _bstr_t("SELECT * FROM mytable WHERE age< ?");<BR>}//try<BR>要注意命令对象必Mq接对象兌h才能起作用,本例中将命o对象的ActiveConnection属性设|ؓq接对象的指针,即ؓ此目的:<BR>Cmd1->ActiveConnection = Conn1;<BR> (2). 创徏参数对象Qƈl参数赋?BR>// Create Parameter Object<BR>Param1 = Cmd1->CreateParameter( _bstr_t(bstrEmpty),<BR>       adInteger,<BR>       adParamInput,<BR>       -1,<BR>        _variant_t( (long) 5) );<BR>Param1->Value = _variant_t( (long) 5 );<BR>Cmd1->Parameters->Append( Param1 );<BR>用命令对象的Ҏ来创Z个参数对象,其中的长度参敎ͼW三个)如果是固定长度的cdQ就?1Q如果是字符串等可变长度的就填其实际长度。Parameters是命令对象的一个容器,它的AppendҎ是把创建的参数对象q加到该容器里。Appendq去的参数按先后序与SQL语句中的问号从左臛_一一对应?BR>(3). 执行命o打开记录?BR>// Open Recordset Object<BR>Rs1 = Cmd1->Execute( &vtEmpty, &vtEmpty2, adCmdText );<BR>但要注意Q用Command和Connection对象的ExecuteҎ得到的Recordset是只ȝ。因为在打开Recordset之前Q我们无法设|它的LockType属性(光认gؓ只读Q。而在打开之后讄LockType不v作用?BR>我发现用上述Ҏ得到记录集Rs1后,不但Rs1中的记录无法修改Q即使直接用SQL语句修改同一表中M记录都不行?BR>要想能修Ҏ据,q是要用Recordset自己的OpenҎ才行Q如Q?BR> try{<BR>   m_pRecordset->Open((IDispatch *) Cmd1, vtMissing,<BR>    adOpenStatic, adLockOptimistic, adCmdUnspecified);<BR>  }<BR>  catch (_com_error &e)<BR>  {<BR>   ::MessageBox(NULL,"mytable表不存在?,"提示",MB_OK | MB_ICONWARNING);<BR>  }<BR>Recordset对象的OpenҎ真是太好了,其第一个参数可以是SQL语句、表名字、命令对象指针等{?BR>9、响应ADO的通知事g<BR>通知事g是当某个特定事件发生时Q由Provider通知客户E序Q换句话_是由Provider调用客户E序中的一个特定的ҎQ即事g的处理函敎ͼ。所以ؓ了响应一个事Ӟ最关键的就是要实现事g的处理函数?BR>(1). 从ConnectionEventsVt接口zZ个类<BR>Z响应_Connection的通知事gQ应该从ConnectionEventsVt接口zZ个类Q?BR>class CConnEvent : public ConnectionEventsVt<BR>{<BR>private:<BR>      ULONG   m_cRef;<BR>public:<BR>      CConnEvent() { m_cRef = 0; };<BR>      ~CConnEvent() {};<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>      STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);<BR>      STDMETHODIMP_(ULONG) AddRef(void);<BR>      STDMETHODIMP_(ULONG) Release(void);<BR>      STDMETHODIMP raw_InfoMessage( <BR>         struct Error *pError,<BR>         EventStatusEnum *adStatus,<BR>         struct _Connection *pConnection);<BR>      STDMETHODIMP raw_BeginTransComplete( <BR>         LONG TransactionLevel,<BR>         struct Error *pError,<BR>         EventStatusEnum *adStatus,<BR>         struct _Connection *pConnection);<BR>  ......<BR>};<BR>(2). 实现每一个事件的处理函数(凡是带raw_前缀的方法都把它实现?Q?BR>STDMETHODIMP CConnEvent::raw_InfoMessage( <BR>         struct Error *pError,<BR>         EventStatusEnum *adStatus,<BR>         struct _Connection *pConnection)<BR>         {<BR>         *adStatus = adStatusUnwantedEvent;<BR>         return S_OK;<BR>         };<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>有些Ҏ虽然你ƈ不需要,但也必须实现它,只需单地q回一个S_OK卛_。但如果要避免经常被调用Q还应在其中adStatus参数讄为adStatusUnwantedEventQ则在本ơ调用后Q以后就不会被调用了?BR>另外q必d现QueryInterface, AddRef, 和Release三个Ҏ: <BR> STDMETHODIMP CConnEvent::QueryInterface(REFIID riid, void ** ppv) <BR> {<BR>      *ppv = NULL;<BR>      if (riid == __uuidof(IUnknown) || <BR>          riid == __uuidof(ConnectionEventsVt)) *ppv = this;<BR>      if (*ppv == NULL)<BR>         return ResultFromScode(E_NOINTERFACE);<BR>      AddRef();<BR>      return NOERROR;<BR>   }<BR>   STDMETHODIMP_(ULONG) CConnEvent::AddRef() { return ++m_cRef; };<BR>   STDMETHODIMP_(ULONG) CConnEvent::Release()<BR>{ <BR>if (0 != --m_cRef) return m_cRef;<BR>delete this;<BR>return 0;<BR>}<BR>(3). 开始响应通知事g<BR> // Start using the Connection events<BR> IConnectionPointContainer   *pCPC = NULL;<BR> IConnectionPoint         *pCP = NULL;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P> hr = pConn.CreateInstance(__uuidof(Connection));<BR>   if (FAILED(hr)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P> hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer), <BR>      (void **)&pCPC);<BR> if (FAILED(hr)) return;<BR> hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);<BR> pCPC->Release();<BR> if (FAILED(hr)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P> pConnEvent = new CConnEvent();<BR>   hr = pConnEvent->QueryInterface(__uuidof(IUnknown), (void **) &pUnk);<BR>   if (FAILED(hr)) return rc; <BR>   hr = pCP->Advise(pUnk, &dwConnEvt);<BR>   pCP->Release();<BR>   if (FAILED(hr)) return;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P> pConn->Open("dsn=Pubs;", "sa", "", adConnectUnspecified); <BR>也就是说在连?Open)之前做q些事?BR>(4). 停止响应通知事g<BR> pConn->Close();<BR> // Stop using the Connection events<BR>  hr = pConn->QueryInterface(__uuidof(IConnectionPointContainer), <BR>      (void **) &pCPC);<BR>   if (FAILED(hr)) return;<BR>   hr = pCPC->FindConnectionPoint(__uuidof(ConnectionEvents), &pCP);<BR>   pCPC->Release();<BR>   if (FAILED(hr)) return rc;<BR>   hr = pCP->Unadvise( dwConnEvt );<BR>   pCP->Release();<BR>   if (FAILED(hr)) return;<BR>在连接关闭之后做qg事?<BR>10、邦定数?BR>定义一个绑定类Q将其成员变量绑定到一个指定的记录集,以方便于讉K记录集的字段倹{?BR>(1). 从CADORecordBindingzZ个类Q?BR>class CCustomRs : public CADORecordBinding<BR>{<BR>BEGIN_ADO_BINDING(CCustomRs)<BR>   ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_fname, <BR>         sizeof(m_szau_fname), lau_fnameStatus, false)<BR>   ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_lname, <BR>         sizeof(m_szau_lname), lau_lnameStatus, false)<BR>   ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_szphone,    <BR>         sizeof(m_szphone),    lphoneStatus,    true)<BR>END_ADO_BINDING()<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>public:<BR>   CHAR   m_szau_fname[22];<BR>   ULONG   lau_fnameStatus;<BR>   CHAR   m_szau_lname[42];<BR>   ULONG   lau_lnameStatus;<BR>   CHAR   m_szphone[14];<BR>   ULONG   lphoneStatus;<BR>};<BR>其中要l定的字D与变量名用BEGIN_ADO_BINDING宏关联v来。每个字D对应于两个变量Q一个存攑֭D늚|另一个存攑֭D늚状态。字D는?开始的序号表示Q如1Q?Q?{等?BR>特别要注意的是:如果要绑定的字段是字W串cdQ则对应的字W数l的元素个数一定要比字D长度大2Q比如m_szau_fname[22]Q其l定的字Dau_fname的长度实际是20Q,不这L定就会失败。我分析多出?可能是ؓ了存攑֭W串l尾的空字符null和BSTR字符串开头的一个字Q表CBSTR的长度)。这个问题对于初学者来说可能是一个意想不到的问题?BR>CADORecordBindingcȝ定义在icrsint.h文g里,内容是:<BR>class CADORecordBinding<BR>{<BR>public:<BR> STDMETHOD_(const ADO_BINDING_ENTRY*, GetADOBindingEntries) (VOID) PURE;<BR>};<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>BEGIN_ADO_BINDING宏的定义也在icrsint.h文g里,内容是:<BR>#define BEGIN_ADO_BINDING(cls) public: \<BR>typedef cls ADORowClass; \<BR>const ADO_BINDING_ENTRY* STDMETHODCALLTYPE GetADOBindingEntries() { \<BR>static const ADO_BINDING_ENTRY rgADOBindingEntries[] = { <FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>ADO_VARIABLE_LENGTH_ENTRY2宏的定义也在icrsint.h文g里:<BR>#define ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, Status, Modify)\<BR> {Ordinal, \<BR> DataType, \<BR> 0, \<BR> 0, \<BR> Size, \<BR> offsetof(ADORowClass, Buffer), \<BR> offsetof(ADORowClass, Status), \<BR> 0, \<BR> classoffset(CADORecordBinding, ADORowClass), \<BR> Modify},<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P> #define END_ADO_BINDING宏的定义也在icrsint.h文g里:<BR> #define END_ADO_BINDING()   {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\<BR> return rgADOBindingEntries;}<BR>(2). l定<BR>_RecordsetPtr   Rs1;<BR>IADORecordBinding   *picRs=NULL;<BR>CCustomRs rs;<BR>......<BR>Rs1->QueryInterface(__uuidof(IADORecordBinding), <BR>               (LPVOID*)&picRs));<BR>picRs->BindToRecordset(&rs);<BR>z出的cd通过IADORecordBinding接口才能l定Q调用它的BindToRecordsetҎp了?BR>(3). rs中的变量x当前记录字段的?BR>//Set sort and filter condition:<BR>// Step 4: Manipulate the data<BR>Rs1->Fields->GetItem("au_lname")->Properties->GetItem("Optimize")->Value = true; <BR>Rs1->Sort = "au_lname ASC";<BR>Rs1->Filter = "phone LIKE '415 5*'";<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>Rs1->MoveFirst();<BR>while (VARIANT_FALSE == Rs1->EndOfFile)<BR>{<BR> printf("Name: %s\t %s\tPhone: %s\n",  <BR>  (rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : ""), <BR>        (rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : ""),<BR>        (rs.lphoneStatus == adFldOK ? rs.m_szphone   : ""));<BR>         if (rs.lphoneStatus == adFldOK)<BR>            strcpy(rs.m_szphone, "777");<BR>         TESTHR(picRs->Update(&rs));   // Add change to the batch<BR>  Rs1->MoveNext();<BR>}<BR>Rs1->Filter = (long) adFilterNone;<BR>......<BR>if (picRs) picRs->Release();<BR>Rs1->Close();<BR>pConn->Close();<BR>只要字段的状态是adFldOKQ就可以讉K。如果修改了字段Q不要忘了先调用picRs的UpdateQ注意不是Recordset的UpdateQ,然后才关闭,也不要忘了释放picRsQ即picRs->Release();Q?BR>(4). 此时q可以用IADORecordBinding接口d新纪?BR> if(FAILED(picRs->AddNew(&rs)))<BR> ......<BR>11. 讉K长数?BR>在Microsoft SQL中的长数据包括text、image{这样长cd的数据,作ؓ二进制字节来对待?BR>可以用Field对象的GetChunk和AppendChunkҎ来访问。每ơ可以读出或写入全部数据的一部分Q它会记住上ơ访问的位置。但是如果中间访问了别的字段后,又得从头来了?BR>L下面的例子:<BR>//写入一张照片到数据库:<BR>VARIANT varChunk;<BR>SAFEARRAY *psa;<BR>SAFEARRAYBOUND rgsabound[1];<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>//VT_ARRAY | VT_UI1<BR>CFile f("h:\\aaa.jpg",CFile::modeRead);<BR>BYTE  bVal[ChunkSize+1];<BR>UINT uIsRead=0;<BR>//Create a safe array to store the array of BYTES  <BR>while(1)<BR>{<BR> uIsRead=f.Read(bVal,ChunkSize);<BR> if(uIsRead==0)break;<BR> rgsabound[0].cElements =uIsRead;<BR>    rgsabound[0].lLbound = 0;<BR> psa = SafeArrayCreate(VT_UI1,1,rgsabound);<BR> for(long index=0;index<uIsRead;index++)          <BR> {<BR>  if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index])))<BR>  ::MessageBox(NULL,"啊,又出毛病了?,"提示",MB_OK | MB_ICONWARNING);<BR> }<BR> varChunk.vt = VT_ARRAY|VT_UI1;<BR> varChunk.parray = psa;<BR> try{<BR>  m_pRecordset->Fields->GetItem("photo")->AppendChunk(varChunk); <BR> }<BR> catch (_com_error &e)<BR> {<BR>  CString str=(char*)e.Description();<BR>  ::MessageBox(NULL,str+"\n又出毛病了?,"提示",MB_OK | MB_ICONWARNING);<BR> }<BR> ::VariantClear(&varChunk);<BR> ::SafeArrayDestroyData( psa);<BR> if(uIsRead<ChunkSize)break;<BR>}//while(1)  <BR>f.Close();<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>//从数据库M张照片:<BR>CFile f;<BR>f.Open("h:\\bbb.jpg",CFile::modeWrite|CFile::modeCreate);<BR>long lPhotoSize = m_pRecordset->Fields->Item["photo"]->ActualSize;  <BR>long lIsRead=0;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>_variant_t varChunk;<BR>BYTE buf[ChunkSize];<BR>while(lPhotoSize>0)<BR>{<BR> lIsRead=lPhotoSize>=ChunkSize? ChunkSize:lPhotoSize;<BR> varChunk = m_pRecordset->Fields-><BR>                  Item["photo"]->GetChunk(lIsRead);<BR> for(long index=0;index<lIsRead;index++)         <BR> {           <BR>  ::SafeArrayGetElement(varChunk.parray,&index,buf+index);   <BR> }<BR> f.Write(buf,lIsRead);<BR> lPhotoSize-=lIsRead;<BR>}//while()<BR>f.Close();<BR>12. 使用SafeArray问题<BR>学会使用SafeArray也是很重要的Q因为在ADO~程中经常要用。它的主要目的是用于automation中的数组型参数的传递。因为在|络环境中,数组是不能直接传递的Q而必d其包装成SafeArray。实质上SafeArray是通常的数l增加一个描q符Q说明其l数、长度、边界、元素类型等信息。SafeArray也ƈ不单独用,而是其再包装到VARIANTcd的变量中Q然后才作ؓ参数传送出厅R在VARIANT的vt成员的值如果包含VT_ARRAY|...,那么它所装的就是一个SafeArrayQ它的parray成员x指向SafeArray的指针。SafeArray中元素的cd可以是VARIANT能封装的McdQ包括VARIANTcd本n?nbsp;<BR>使用SafeArray的具体步骤:<BR>Ҏ一Q?BR> 包装一个SafeArrayQ?BR>(1). 定义变量Q如Q?BR> VARIANT varChunk;<BR> SAFEARRAY *psa;<BR>    SAFEARRAYBOUND rgsabound[1];<BR>(2). 创徏SafeArray描述W:<BR> uIsRead=f.Read(bVal,ChunkSize);//read array from a file.<BR> if(uIsRead==0)break;<BR> rgsabound[0].cElements =uIsRead;<BR> rgsabound[0].lLbound = 0;<BR> psa = SafeArrayCreate(VT_UI1,1,rgsabound);<BR>(3). 攄数据元素到SafeArrayQ?BR> for(long index=0;index<uIsRead;index++)          <BR> {<BR>  if(FAILED(SafeArrayPutElement(psa,&index,&bVal[index])))<BR>   ::MessageBox(NULL,"出毛病了?,"提示",MB_OK | MB_ICONWARNING);<BR> }<BR> 一个一个地放,挺麻烦的?BR>(4). 装到VARIANT内:<BR> varChunk.vt = VT_ARRAY|VT_UI1;<BR> varChunk.parray = psa;<BR> q样可以将varChunk作ؓ参数传送出M?FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P> dSafeArray中的数据的步骤:<BR>(1). 用SafeArrayGetElement一个一个地?BR> BYTE buf[lIsRead];<BR> for(long index=0;index<lIsRead;index++)         <BR> {           <BR>  ::SafeArrayGetElement(varChunk.parray,&index,buf+index);   <BR> }<BR> p到缓冲区buf里了?BR>Ҏ二:<BR> 使用SafeArrayAccessData直接dSafeArray的缓冲区Q?BR>(1). ȝ冲区Q?BR> BYTE *buf;<BR> SafeArrayAccessData(varChunk.parray, (void **)&buf);<BR> f.Write(buf,lIsRead);<BR> SafeArrayUnaccessData(varChunk.parray);<BR>(2). 写缓冲区Q?BR> BYTE *buf;<BR> ::SafeArrayAccessData(psa, (void **)&buf);<BR> for(long index=0;index<uIsRead;index++)          <BR> {<BR>  buf[index]=bVal[index];  <BR> }<BR> ::SafeArrayUnaccessData(psa);<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P> varChunk.vt = VT_ARRAY|VT_UI1;<BR> varChunk.parray = psa;<FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>q种ҎdSafeArray都可以,它直接操USafeArray的数据缓冲区Q比用SafeArrayGetElement和SafeArrayPutElement速度快。特别适合于读取数据。但用完之后不要忘了调用::SafeArrayUnaccessData(psa)Q否则会出错的?BR>13. 使用书签( bookmark )<BR>书签可以唯一标识记录集中的一个记录,用于快速地当前记录移回到已访问过的记录,以及q行qo{等。Provider会自动ؓ记录集中的每一条记录生一个书{,我们只需要用它p了。我们不能试图显C、修Ҏ比较书签。ADO用记录集的Bookmark属性表C当前记录的书签?BR>用法步骤Q?BR>(1). 建立一个VARIANTcd的变?BR>_variant_t VarBookmark;<BR>(2). 当前记录的书签值存入该变量<BR>也就是记录集的Bookmark属性的当前倹{?BR> VarBookmark = rst->Bookmark;<BR>(3). q回到先前的记录<BR>保存的书签D|到记录集的书签属性中Q?BR> // Check for whether bookmark set for a record<BR> if (VarBookmark.vt == VT_EMPTY)<BR>  printf("No Bookmark set!\n");<BR> else <BR>  rst->Bookmark = VarBookmark;<BR>讄完后Q当前记录即会移动到该书{指向的记录?BR>14、设|过滤条?BR>Recordset对象的Filter属性表CZ当前的过滤条件。它的值可以是以AND或ORq接h的条件表辑ּQ不含WHERE关键字)、由书签l成的数l或ADO提供的FilterGroupEnum枚D倹{ؓFilter属性设|新值后Recordset的当前记录指针会自动Ud到满滤条件的W一个记录。例如:<BR>rst->Filter  = _bstr_t ("姓名='赵薇'  AND  性别=’女?);<BR>在用条件表辑ּ时应注意下列问题Q?BR>Q?Q、可以用圆括L成复杂的表达?BR>例如Q?BR>rst->Filter  =  _bstr_t ("(姓名='赵薇'  AND  性别=’女?  OR  AGE<25");<BR>但是微Y不允许在括号内用ORQ然后在括号外用ANDQ例如:<BR>rst->Filter  = _bstr_t ("(姓名='赵薇'  OR 性别=’女?  AND  AGE<25");<BR>必须修改为:<BR>rst->Filter  = _bstr_t ("(姓名='赵薇'  AND  AGE<25)  OR  (性别=’女?nbsp; AND  AGE<25)");<BR>Q?Q、表辑ּ中的比较q算W可以是LIKE<BR>LIKE后被比较的是一个含有通配W?的字W串Q星可Cq个L的字W?BR>字符串的首部和尾部可以同时带星号*<BR>rst->Filter  =  _bstr_t ("姓名 LIKE '*?' ");<BR>也可以只是尾部带星号Q?BR>rst->Filter  =  _bstr_t ("姓名 LIKE '?' ");<BR>Filter属性值的cd是VariantQ如果过滤条件是׃{成的数组Q则需该数组转换为SafeArrayQ然后再装C个VARIANT或_variant_t型的变量中,再赋lFilter属性?BR>15、烦引与排序<BR>Q?Q、徏立烦?BR>当以某个字段为关键字用FindҎ查找ӞZ加快速度可以以该字段为关键字在记录集内部临时建立索引。只要将该字D늚Optimize属性设|ؓtrue卛_Q例如:<BR>pRst->Fields->GetItem("姓名")->Properties-><BR>            GetItem("Optimize")->PutValue("True");<BR>pRst->Find("姓名 = '赵薇'",1,adSearchForward);<BR>......<BR>pRst->Fields->GetItem("姓名")->Properties-><BR>            GetItem("Optimize")->PutValue("False");<BR>pRst->Close();<BR>说明QOptimize属性是由Provider提供的属性(在ADO中称为动态属性)QADO本n没有此属性?BR>Q?Q、排?BR>要排序也很简单,只要把要排序的关键字列表讄到Recordset对象的Sort属性里卛_Q例如:<BR>pRstAuthors->CursorLocation = adUseClient;<BR>pRstAuthors->Open("SELECT * FROM mytable",<BR>            _variant_t((IDispatch *) pConnection),<BR>            adOpenStatic, adLockReadOnly, adCmdText);<BR>......<BR>pRst->Sort = "姓名 DESC, q龄 ASC";<BR>关键字(卛_D名Q之间用逗号隔开Q如果要以某关键字降序排序,则应在该关键字后加一I格Q再加DESCQ如上例Q。升序时ASC加不加无所谓。本操作是利用烦引进行的Qƈ未进行物理排序,所以效率较高?BR>但要注意Q在打开记录集之前必d记录集的CursorLocation属性设|ؓadUseClientQ如上例所C。Sort属性值在需要时随时可以修改?BR>16、事务处?BR>ADO中的事务处理也很单,只需分别在适当的位|调用Connection对象的三个方法即可,q三个方法是Q?BR>Q?Q、在事务开始时调用<BR>pCnn->BeginTrans();<BR>Q?Q、在事务l束q成功时调用<BR>pCnn->CommitTrans ();<BR>Q?Q、在事务l束q失败时调用<BR>pCnn->RollbackTrans ();<BR>在用事务处理时Q应量减小事务的范_卛_从事务开始到l束Q提交或回滚Q之间的旉间隔Q以便提高系l效率。需要时也可在调用BeginTrans()Ҏ之前Q先讄Connection对象的IsolationLevel属性|详细内容参见MSDN中有关ADO的技术资料?BR>三、用ADO~程常见问题解答<BR>以下均是针对MS SQL 7.0~程时所遇问题进行讨论?BR>1、连接失败可能原?BR>Enterprise Managemer内,打开服务器的属性对话框Q在Security选项卡中Q有一个选项Authentication?BR>如果该选项是Windows NT onlyQ则你的E序所用的q接字符串就一定要包含Trusted_Connection参数Qƈ且其值必MؓyesQ如Q?BR>"Provider=SQLOLEDB;Server=888;Trusted_Connection=yes"<BR>  ";Database=master;uid=lad;";<BR>如果不按上述操作Q程序运行时q接必然p|?BR>如果Authentication选项是SQL Server and Windows NTQ则你的E序所用的q接字符串可以不包含Trusted_Connection参数Q如Q?BR>"Provider=SQLOLEDB;Server=888;Database=master;uid=lad;pwd=111;";<BR>因ؓADOl该参数取的默认值就是noQ所以可以省略。我认ؓq是取默认值比较安全一些?BR>2、改变当前数据库的方?BR>使用Tansct-SQL中的USE语句卛_?BR>3、如何判断一个数据库是否存在<BR>(1)、可打开master数据库中一个叫做SCHEMATA的视图,其内容列Z该服务器上所有的数据库名U?BR>(2) 、更便的Ҏ是用USE语句Q成功了存在;不成功,׃存在。例如:<BR> try{<BR>  m_pConnect->Execute ( _bstr_t("USE INSURANCE_2002"),NULL,<BR>  adCmdText|adExecuteNoRecords );<BR> }<BR> catch (_com_error &e)<BR> {<BR>  blSuccess=FALSE;<BR>  CString str="数据库INSURANCE_2002不存在!\n";<BR>  str+=e.Description();<BR>  ::MessageBox(NULL,str,"警告",MB_OK | MB_ICONWARNING); <BR> }<BR>4、判断一个表是否存在<BR>Q?Q、同样判断一个表是否存在Q也可以用是否成功地打开它来判断Q十分方便,例如Q?BR> try{<BR>  m_pRecordset->Open(_variant_t("mytable"),<BR>            _variant_t((IDispatch *)m_pConnection,true), adOpenKeyset,<BR>            adLockOptimistic, adCmdTable);<BR> }<BR> catch (_com_error &e)<BR> {<BR>  ::MessageBox(NULL,"该表不存在?,"提示",MB_OK | MB_ICONWARNING);<BR> }</P> <P>(2)、要不然可以采用ȝ一点的办法Q就是在MS-SQL服务器上的每个数据库中都有一个名为sysobjects的表Q查看此表的内容即知指定的表是否在该数据库中?BR>(3)、同P每个数据库中都有一个名为TABLES的视?View)Q查看此视图的内容即知指定的表是否在该数据库中?BR>5、类型{换问?BR>Q?Q、类型VARIANT_BOOL<BR>cdVARIANT_BOOL{h于shortcd。The VARIANT_BOOL is equivalent to short. see it's definition below: <BR>typdef short VARIANT_BOOL<BR>Q?Q、_com_ptr_tcȝcd转换<BR>_ConnectionPtr可以自动转换成IDspatch*cdQ这是因为_ConnectionPtr实际上是_com_ptr_tcȝ一个实例,而这个类有此cd转换函数?BR>同理Q_RecordsetPtr和_CommandPtr也都可以q样转换?BR>Q?Q、_bstr_t和_variant_tc?BR>在ADO~程Ӟ_bstr_t和_variant_tq两个类很有用,省去了许多BSTR和VARIANTcd转换的麻烦?BR>6、打开记录集时的问?BR>在打开记录集时Q在调用Recordset的OpenҎӞ其最后一个参数里一定不能包含adAsyncExecuteQ否则将因ؓ是异步操作,在读取数据时无法d数据?BR>7、异常处理问?BR>Ҏ有调用ADO的语句一定要用try和catch语句捕捉异常Q否则在发生异常ӞE序会异帔R出?BR>8、用SafeArray问题<BR>在初学用中Q我NC个伤脑筋的问题,一定要注意Q?BR>在定义了SAFEARRAY的指针后Q如果打重复用多ơ,则在中间可以调用::SafeArrayDestroyData释放数据Q但决不能调?:SafeArrayDestroyDescriptorQ否则必然出错,即调用SafeArrayCreate也不行。例如:<BR>SAFEARRAY *psa;<BR>......<BR>//When the data are no longer to be used:<BR>::SafeArrayDestroyData( psa);<BR>我分析在定义psa指针Ӟ一个SAFEARRAY的实例(也就是SAFEARRAY描述W)也同时被自动建立了。但是只要一调用::SafeArrayDestroyDescriptorQ描q符p销毁了?BR>所以我认ؓ::SafeArrayDestroyDescriptor可以Ҏ׃调用Q即使调用也必须在最后调用?BR>9、重复用命令对象问?BR>一个命令对象如果要重复使用多次Q尤其是带参数的命oQ,则在W一ơ执行之前,应将它的Prepared属性设|ؓTRUE。这样会使第一ơ执行减慢,但却可以使以后的执行全部加快?BR>10、绑定字W串型字D问?BR>如果要绑定的字段是字W串cdQ则对应的字W数l的元素个数一定要比字D长度大2Q比如m_szau_fname[22]Q其l定的字Dau_fname的长度实际是20Q,不这L定就会失败?BR>11、用AppendChunk的问?BR>当用AddNewҎ刚刚向记录集内添加一个新记录之后Q不能首先向一个长数据字段QimagecdQ写入数据,必须先向其他字段写入q数据之后,才能调用AppendChunk写该字段Q否则出错。也是_AppendChunk不能紧接在AddNew之后。另外,写入其他字段后还必须紧接着调用AppendChunkQ而不能调用记录集的UpdateҎ后,才调用AppendChunkQ否则调用AppendChunk时也会出错。换句话_是必须AppendChunk在前QUpdate在后。因而这个时候就不能使用带参数的AddNew了,因ؓ带参数的AddNew会自动调用记录集的UpdateQ所以AppendChunkp到Update的后面了Q就只有出错了!因此Q这时应该用不带参数的AddNew?BR>我推这可能是MS SQL 7.0的问题,在MS SQL 2000中则不存在这些问题,但是AppendChunk仍然不能在Update之后?BR>四、小l?BR>一般情况下QConnection和Command的Execute用于执行不生记录集的命令,而Recordset的Open用于产生一个记录集Q当然也不是l对的。特别Command主要是用于执行参数化的命令,可以直接由Command对象执行Q也可以Command对象传递给Recordset的Open?BR>本文中的代码片断均在VC++ 6.0、Windows NT 4.0 SP6和MS SQL 7.0中调试通过。相信您读过之后Q编写简单的数据库程序应该没有问题了。当然要~写比较实用的、复杂一点的E序Q还需要对OLE DB、ADO以及数据库^台再多了解一点,希望您l努力,一定会很快成功的!详细参考资料请参见微YMSDN July 2000光盘或MS SQL 7.0在线文档资料QBooks onlineQ。文中难免有错误和不妥之处,敬请各位批评指正Q?FONT color=#ffffcc>www.chinai tp 采吧采吧不是|?ow er.comJuJIe</FONT></P> <P>参考文献:<BR>1?微YMSDN Library - July 2000 / Platform SDK / Data Services / Microsoft Data Access Components (MDAC) / Microsoft ActiveX Data Objects (ADO)<BR>2?微YMS SQL 7.0在线文档资料QBooks onlineQ?--- Building SQL Server Applications / ADO and SQL Server<BR>3?微YMS SQL 7.0在线文档资料QBooks onlineQ?--- Building SQL Server Applications / Transact ?SQL Reference<BR>4?微YMSDN Library - July 2000 / Platform SDK / Data Services / Microsoft Data Access Components (MDAC) / Microsoft OLE DB</P><img src ="http://www.shnenglu.com/ivenher/aggbug/1773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ivenher/" target="_blank">爱饭?/a> 2005-12-15 11:03 <a href="http://www.shnenglu.com/ivenher/articles/1773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VC数据库编E中的打印控?/title><link>http://www.shnenglu.com/ivenher/articles/1079.html</link><dc:creator>爱饭?/dc:creator><author>爱饭?/author><pubDate>Fri, 11 Nov 2005 06:31:00 GMT</pubDate><guid>http://www.shnenglu.com/ivenher/articles/1079.html</guid><wfw:comment>http://www.shnenglu.com/ivenher/comments/1079.html</wfw:comment><comments>http://www.shnenglu.com/ivenher/articles/1079.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ivenher/comments/commentRss/1079.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ivenher/services/trackbacks/1079.html</trackback:ping><description><![CDATA[<TABLE style="TABLE-LAYOUT: fixed; WORD-BREAK: break-all" cellSpacing=0 cellPadding=0 width="100%" border=0> <TBODY> <TR> <TD style="FONT-SIZE: 22px" align=middle height=60>VC数据库编E中的打印控?/TD></TR> <TR> <TD style="FONT-SIZE: 9pt" align=middle height=30><FONT color=#00ff00>2003-12-4</FONT>加入  来自<FONT color=#00ff00>赛_|?/FONT>  作?FONT color=#00ff00>李佑?/FONT>  <FONT color=#00ff00>1</FONT>条评?nbsp; 点击<FONT color=#ff0000>2287</FONT>?/TD></TR> <TR> <TD style="FONT-SIZE: 14px" width="100%">       <BR>  VC数据库编E中的打印控制比较复杂,但它也给E序员最大的灉|性,而这U灵zL正是我们需要的。因为各行业、部门的报表一般都不太规整Q特别是表头部分Q二、三重嵌套的情况很常见。下面我们就开发中到的一些问题与同行们探讨?nbsp;<BR><BR>  Document/View框架之外的打?nbsp;<BR><BR>  熟悉VC的程序员都知道Microsoft 的AppWizard生成的应用程序框架中Q可以选择免费的打印及打印预览功能Q但前提是必选择Document/Viewl构。然而我们的数据库应用中一般都不需要一个文档类来保存文档,因ؓ数据库(源)是我们的文档,数据一般是在一个对话框或视中与用户交互Q编辑或修改l果直接通过数据库引擎写回数据库中。我们的E序L架要么是Z对话框的、要么是Z无文档类的单视(或多视)l构Q在q种情况下,AppWizard 在打印控刉分ƈ不能l我们Q何帮助,只能自己负责完成打印控制?nbsp;<BR><BR>  ȝhQ一ơ打印操作要遵@以下步骤Q?nbsp;<BR><BR>  1.得到或生成打印设备场景,可通过昄打印对话框让用户选择打印ZU张{设|,也可在程序中直接取系l缺省打印机讄Q然后根据报表格式设|纸张大和打印方向Q?nbsp;<BR><BR>  2.开始在该设备场景中的一ơ打C业,实际打印报表内容Q终止打C业; <BR><BR>  3.清除打印讑֤场景Q完成本ơ打印操作?nbsp;<BR><BR>  在下面的例子中,我们在一个对话框中让用户选择打印某个报表Q没有显C打印设|对话框Q而是直接取系l缺省打印机讄Q然后根据报表格式设|纸张大和打印方向。之所以这样做是因为各行业、部门的报表格式一般都是至上而下的统一格式。函数DoPreparePrintDC()、DoPrint()和DoClearPrintDC()分别对应上述的三个步骤: <BR><BR>  BOOL CMyDialog::DoPreparePrintDC() <BR><BR>  // 准备打印场景 <BR><BR>  { <BR><BR>   Qdefine  FONTSIZE 14 <BR><BR>   // 获取打印机的讑֤属?nbsp;<BR><BR>   CPrintDialog dlgPrint( FALSE ); <BR><BR>   // 得到当前pȝ~省打印|?nbsp;<BR><BR>   if(!dlgPrint.GetDefaults()) return FALSE; <BR><BR>   LPDEVMODE pDM=dlgPrint.GetDevMode(); <BR><BR>   if(pDM==NULL) return FALSE; <BR><BR>   ::GlobalUnlock(pDM); <BR><BR>   // 联结打印DCQm—hDC是定义ؓHDC m—hDC的类成员变量 <BR><BR>   m—hDC=dlgPrint.CreatePrinterDC(); <BR><BR>   // m—DC是定义ؓCDC m—DC的类成员变量 <BR><BR>   if(!m—DC.Attach(m—hDC) return FALSE; <BR><BR>   // 讄打印标志 <BR><BR>   m—DC.m—bPrinting=TRUE; <BR><BR>   short cxInch=m—DC.GetDeviceCaps(LOGPIXELSX); <BR><BR>   short cyInch=m—DC.GetDeviceCaps(LOGPIXELSY); <BR><BR>   // 建立打印字体Qm—fontPrint 是定义ؓCFont m_fontPrint的类成员变量 <BR><BR>   if(!m—fontPrint.CreateFont(MulDiv(FONTSIZE, QcyInch, 72),0,0,0, FW—NORMAL,0,0,0, GB2312—CHARSET, OUT—CHARACTER—PRECIS, CLIP—CHARACTER—PRECIS,DEFAULT—QUALITY, DEFAULT—PITCH|FF—DONTCARE, HFONTNAME) <BR><BR>   return FALSE; <BR><BR>   return TRUE;} <BR><BR>  void CDlgDataPrint::DoClearPrintDC() <BR><BR>  // 清除打印场景 <BR><BR>  { m—fontPrint.DeleteObject(); <BR><BR>   m—DC.Detach(); <BR><BR>   ::DeleteDC( m—hDC );} <BR><BR>  void CDlgDataPrint::DoPrint() <BR><BR>  // 实际打印输出 <BR><BR>  { if(DoPreparePrintDC()==FALSE) return; <BR><BR>   // 开始一ơ打C?nbsp;<BR><BR>   CString str; <BR><BR>   str.LoadString(AFX—IDS—APP—TITLE); <BR><BR>   DOCINFO di; <BR><BR>   ::ZeroMemory (Qdi, sizeof (DOCINFO)); <BR><BR>   di.cbSize=sizeof (DOCINFO); <BR><BR>   di.lpszDocName=str; <BR><BR>   m—DC.StartDoc(Qdi); <BR><BR>   m—DC.StartPage(); <BR><BR>   // 打印字体选进讑֤场景 <BR><BR>   CFontQ?nbsp;pOldFont=m—DC.SelectObject(Qm—fontPrint); <BR><BR>   // 输出报表Q徏议用CDC::DrawText()函数便于控制打印范围 <BR><BR>   ... <BR><BR>   // l止打印作业 <BR><BR>   m—DC.EndPage(); <BR><BR>   m—DC.EndDoc(); <BR><BR>   m—DC.SelectObject(pOldFont); <BR><BR>   // 清除打印场景 <BR><BR>   DoClearPrintDC();} <BR><BR>  表格问题 <BR><BR>  Ҏ式固定或表头、表体比较复杂的情况Q特别是有嵌套表格的情况下,我们认ؓ先将打印l果以文本Ş式写入一临时文gQ然后再Ҏ件进行打印输出的Ҏ会事情单一些。因样在E序中就可以只关心数?表体)的输出,而表头则可以固定格式存入数据库?nbsp;<BR><BR>  但是Q我们在Ҏ本Ş式的报表q行打印输出时却发现一个有的现象Q有时输出结果的盔R两行表格竖线不能寚wQ而有时又可以。原来是 Windows 囑Ş输出的问题,只要我们在徏立打印字体时Q字体的高度是偶数就可保证竖U对齐,如果是奇数则不能寚w。知道了原因Q在建立打印字体时只需加入如下代码卛_Q?nbsp;<BR><BR>  ... <BR><BR>  Qdefine  FONTSIZE 14 <BR><BR>  Qdefine  HFONTNAME ‛_体?nbsp;<BR><BR>  // 建立打印字体Qm—fontPrint是定义ؓCFont m—fontPrint的类成员变量 <BR><BR>  int nFontHeight=MulDiv(FONTSIZE,QcyInch, 72); <BR><BR>  if(nFontHeight Q?nbsp;2) nFontHeightQ+; <BR><BR>  if(!m—fontPrint.CreateFont(nFontHeight, 0, 0, 0, FW—NORMAL, 0, 0,0,GB2312—CHARSET, OUT—CHARACTER—PRECIS, CLIP—CHARACTER—PRECIS,DEFAULT—QUALITY, DEFAULT—PITCH | FF—DONTCARE, HFONTNAME)) <BR><BR>   return FALSE; <BR><BR>  ... <BR><BR>  q有一点小技巧,输出文本形式的报表时Q对报表的横U只需要输出其正常高度的二分之一或三分之一Q这h表看h更紧凑美观。这也是我们在前面徏议用CDC::DrawText()q行l制输出的原因?nbsp;<BR></TD></TR></TBODY></TABLE><img src ="http://www.shnenglu.com/ivenher/aggbug/1079.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ivenher/" target="_blank">爱饭?/a> 2005-11-11 14:31 <a href="http://www.shnenglu.com/ivenher/articles/1079.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ADO开发中如何得到表格字段?/title><link>http://www.shnenglu.com/ivenher/articles/1055.html</link><dc:creator>爱饭?/dc:creator><author>爱饭?/author><pubDate>Fri, 11 Nov 2005 03:09:00 GMT</pubDate><guid>http://www.shnenglu.com/ivenher/articles/1055.html</guid><wfw:comment>http://www.shnenglu.com/ivenher/comments/1055.html</wfw:comment><comments>http://www.shnenglu.com/ivenher/articles/1055.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ivenher/comments/commentRss/1055.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ivenher/services/trackbacks/1055.html</trackback:ping><description><![CDATA[<BR>1. 代码说明 <BR>(1)?stdafx.h 加入如下代码引入 ADO 库定?A target=_blank>文g</A>Q?PRE>#import "c:\program files\common files\system\ado\msado15.dll" no_namespace rename ("EOF", "adoEOF") </PRE>(2)初始化COM库,在BOOL CGetFieldNameApp::InitInstance()中添加AfxOleInit(); <P></P><BR>(3)在类 CgetFieldNameDlg 中添加两个用于打开<A target=_blank>数据?/A>q接和打开记录集的变量Q?PRE>_ConnectionPtr m_pConnection; _RecordsetPtr m_pRecordset; </PRE>(4) 在CgetFieldNameDlg的构造函Cd<A target=_blank>数据?/A>q接和记录集初始化代码;<PRE>m_pConnection.CreateInstance(__uuidof(Connection)); try { m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\\FTI.mdb", "", "", adModeUnknown ); } catch(_com_error e) { AfxMessageBox("<A target=_blank>数据?/A>q接p|!"); } m_pRecordset.CreateInstance(__uuidof(Recordset));</PRE>(5) lListbox控gd控g变量m_FieldsListQ?BR>(6) 在按钮的单击事g中添加相应代码;<PRE>_bstr_t mStrSQL; CString strColName; BSTR bstrColName; long ColCount,i; Field * field = NULL; HRESULT hr; Fields * fields = NULL; LPCTSTR nameField; //打开记录集,得到字段名,q将字段名信息添加到ListBox? mStrSQL = "SELECT * FROM Images"; m_pRecordset->Open(mStrSQL, m_pConnection.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText); hr = m_pRecordset->get_Fields (&fields); //得到记录集的字段集和 if(SUCCEEDED(hr)) fields->get_Count(&ColCount); //得到记录集的字段集合中的字段的M? for(i=0;i<ColCount;i++) { fields->Item[i]->get_Name(&bstrColName); //得到记录?/中的字段? strColName=bstrColName; nameField = strColName; m_FieldsList.AddString(nameField); } if(SUCCEEDED(hr)) fields->Release();//释放指针 </PRE><img src ="http://www.shnenglu.com/ivenher/aggbug/1055.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ivenher/" target="_blank">爱饭?/a> 2005-11-11 11:09 <a href="http://www.shnenglu.com/ivenher/articles/1055.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用udl建立到sybase的连?/title><link>http://www.shnenglu.com/ivenher/articles/1012.html</link><dc:creator>爱饭?/dc:creator><author>爱饭?/author><pubDate>Wed, 09 Nov 2005 08:25:00 GMT</pubDate><guid>http://www.shnenglu.com/ivenher/articles/1012.html</guid><wfw:comment>http://www.shnenglu.com/ivenher/comments/1012.html</wfw:comment><comments>http://www.shnenglu.com/ivenher/articles/1012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ivenher/comments/commentRss/1012.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ivenher/services/trackbacks/1012.html</trackback:ping><description><![CDATA[<P>新徏一个udl文g。选择提供E序。如下图<BR><IMG height=437 alt=选择提供E序.JPG src="http://www.shnenglu.com/images/cppblog_com/ivenher/选择提供E序.JPG" width=419 border=0><BR><BR>选择下一步?BR><IMG height=437 alt=W二?JPG src="http://www.shnenglu.com/images/cppblog_com/ivenher/W二?JPG" width=419 border=0><BR><BR>数据源ؓ利用 sybase ase ole Configuration Manager所建立的数据源?/P><img src ="http://www.shnenglu.com/ivenher/aggbug/1012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ivenher/" target="_blank">爱饭?/a> 2005-11-09 16:25 <a href="http://www.shnenglu.com/ivenher/articles/1012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Connection大全http://www.shnenglu.com/ivenher/articles/1008.html爱饭?/dc:creator>爱饭?/author>Wed, 09 Nov 2005 07:16:00 GMThttp://www.shnenglu.com/ivenher/articles/1008.htmlhttp://www.shnenglu.com/ivenher/comments/1008.htmlhttp://www.shnenglu.com/ivenher/articles/1008.html#Feedback0http://www.shnenglu.com/ivenher/comments/commentRss/1008.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/1008.html1.Sqlserver
  A.ODBC
    I.Standard Security:
      "Driver={SQL Server};Server=Aron1;Database=pubs;Uid=sa;Pwd=asdasd;" 
    II.Trusted connection:
      "Driver={SQL Server};Server=Aron1;Database=pubs;
       Trusted_Connection=yes;" 
    III.Prompt for username and password:
       oConn.Properties("Prompt") = adPromptAlways
       oConn.Open "Driver={SQL Server};Server=Aron1;DataBase=pubs;" 
  B.OLE DB, OleDbConnection (.NET) 
    I.Standard Security:
       "Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;User 
       Id=sa;Password=asdasd;"
    II.Trusted Connection:
       "Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;
       Integrated Security=SSPI;" 
       (仅适用于Sqlserver 2000)
    III.Prompt for username and password:
       oConn.Provider = "sqloledb"
       oConn.Properties("Prompt") = adPromptAlways
       oConn.Open "Data Source=Aron1;Initial Catalog=pubs;"  
    IV.Connect via an IP address:
       "Provider=sqloledb;Data Source=190.190.200.100,1433;Network
       Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;" 
  C.SqlConnection (.NET) 
    I.Standard Security:
     "Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;" 
     或?Server=Aron1;Database=pubs;User ID=sa;Password=asdasd;
     Trusted_Connection=False" 
    II.Trusted Connection:
     "Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;" 
     或?Server=Aron1;Database=pubs;Trusted_Connection=True;" 
     (仅适用于Sqlserver 2000)
    III.Connect via an IP address:
     "Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial 
     Catalog=pubs;User ID=sa;Password=asdasd;" 
     Name       Network library 
     dbnmpntw   Win32 Named Pipes 
     dbmssocn   Win32 Winsock TCP/IP 
     dbmsspxn   Win32 SPX/IPX 
     dbmsvinn   Win32 Banyan Vines 
     dbmsrpcn   Win32 Multi-Protocol (Windows RPC) 
     通过SQLOLEDB provider q接Q用Network Library=dbmssocnQ通过MSDASQL
     providerq接Q用Network=dbmssocn 
    IV.声明ҎQ?
     C#:
       using System.Data.SqlClient;
       SqlConnection oSQLConn = new SqlConnection();
       oSQLConn.ConnectionString="my connectionstring";
       oSQLConn.Open(); 
     VB.NET:
       Imports System.Data.SqlClient
       Dim oSQLConn As SqlConnection = New SqlConnection()
       oSQLConn.ConnectionString="my connectionstring"
       oSQLConn.Open() 
  D.Data Shape 
    MS Data Shape
    "Provider=MSDataShape;Data Provider=SQLOLEDB;Data Source=Aron1;Initial
    Catalog=pubs;User ID=sa;Password=asdasd;" 
   呵呵QData Shape没用q,请参?
    http://www.4guysfromrolla.com/webtech/092599-1.shtml
2.Access 
  A.ODBC 
    I.Standard Security:
      "Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;
       Uid=Admin;Pwd=;" 
    II.Workgroup:
      "Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;
      SystemDB=C:\mydatabase.mdw;" 
    III.Exclusive:
      "Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;
      Exclusive=1;Uid=admin;Pwd="
  B.OLE DB, OleDbConnection (.NET) 
    I.Standard security:
      "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;
      User Id=admin;Password=;" 
    II.Workgroup (system database):
      "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;
      Jet OLEDB:System Database=system.mdw;" 
    III.With password:
      "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;
      Jet OLEDB:Database Password=MyDbPassword;" 
3.Oracle 
  A.ODBC 
    I.New version:
      "Driver={Microsoft ODBC for Oracle};Server=OracleServer.world;
      Uid=Username;Pwd=asdasd;" 
    II.Old version:
      "Driver={Microsoft ODBC Driver for Oracle};ConnectString=
      OracleServer.world;Uid=myUsername;Pwd=myPassword;" 
  B.OLE DB, OleDbConnection (.NET) 
    I.Standard security:
      "Provider=msdaora;Data Source=MyOracleDB;User Id=UserName;
      Password=asdasd;" 
      注:上面是用MS的驱动,下面是用Oracle提供的驱动:
      "Provider=OraOLEDB.Oracle;Data Source=MyOracleDB;User
      Id=Username;Password=asdasd;" 
    II.Trusted Connection:
      "Provider=OraOLEDB.Oracle;Data Source=MyOracleDB;OSAuthent=1;" 
  C.OracleConnection (.NET) 
    I.Standard:
      "Data Source=Oracle8i;Integrated Security=yes"; 
      注:此写法用于Oracle 8i release 3及以上版本?
      声明Ҏ:
      C#:
      using System.Data.OracleClient;
      OracleConnection oOracleConn = new OracleConnection();
      oOracleConn.ConnectionString = "my connectionstring";
      oOracleConn.Open(); 
      VB.NET:
      Imports System.Data.OracleClient
      Dim oOracleConn As OracleConnection = New OracleConnection()
      oOracleConn.ConnectionString = "my connectionstring"
      oOracleConn.Open() 
  D.Data Shape 
    I.MS Data Shape:
      "Provider=MSDataShape.1;Persist Security Info=False;Data 
      Provider=MSDAORA;Data Source=orac;user id=username;password=mypw"
3.MySQL 
  A.ODBC 
    I.Local database:
      "Driver={mySQL};Server=mySrvName;Option=16834;Database=mydatabase;" 
    II.Remote database:
      "Driver={mySQL};Server=data.domain.com;Port=3306;Option=131072;
      Stmt=;Database=my-database;Uid=username;Pwd=password;" 
  B.OLE DB, OleDbConnection (.NET) 
    I.Standard:
      "Provider=MySQLProv;Data Source=mydb;User Id=UserName;
      Password=asdasd;" 
  C.MySqlConnection (.NET) 
    I.eInfoDesigns.dbProvider:
      "Data Source=server;Database=mydb;User ID=username;
      Password=pwd;Command Logging=false" 
      注:此写法仅用于通过eInfoDesigns dbProviderq接Q?
    II.声明ҎQ?
      C#:
      using eInfoDesigns.dbProvider.MySqlClient;
      MySqlConnection oMySqlConn = new MySqlConnection();
      oMySqlConn.ConnectionString = "my connectionstring";
      oMySqlConn.Open(); 
      VB.NET:
      Imports eInfoDesigns.dbProvider.MySqlClient
      Dim oMySqlConn As MySqlConnection = New MySqlConnection()
      oMySqlConn.ConnectionString = "my connectionstring"
      oMySqlConn.Open()   
4.Interbase 
  A.ODBC (Easysoft ODBC-Interbase driver ) 
   I.Local computer:
     "Driver={Easysoft IB6 ODBC};Server=localhost;Database=localhost:
     C:\mydatabase.gdb;Uid=username;Pwd=password" 
   II.Remote Computer:
     "Driver={Easysoft IB6 ODBC};Server=ComputerName;Database=ComputerName
     :C:\mydatabase.gdb;Uid=username;Pwd=password" 
  B.ODBC (Intersolv ODBC-Interbase driver )
   I.Local computer:
     "Driver={INTERSOLV InterBase ODBC Driver (*.gdb)};Server=localhost;
     Database=localhost:C:\mydatabase.gdb;Uid=username;Pwd=password" 
   II.Remote Computer:
     "Driver={INTERSOLV InterBase ODBC Driver (*.gdb)};
     Server=ComputerName;Database=ComputerName:C:\mydatabase.gdb;
     Uid=username;Pwd=password" 
  C.OLE DB (SIBPROvider Driver) 
   I.Standard:
     "provider=sibprovider;location=localhost:;data source=c:
     \databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey" 
   II.Specifying character set:
     "provider=sibprovider;location=localhost:;data source=c:
     \databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey;
     character set=ISO8859_1" 
   III.Specifying role:
     "provider=sibprovider;location=localhost:;data source=c:
     \databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey;
     role=DIGITADORES"
6.IBM DB2 
  A.OLE DB, OleDbConnection (.NET) from ms 
   I.TCP/IP:
     "Provider=DB2OLEDB;Network Transport Library=TCPIP;Network 
     Address=XXX.XXX.XXX.XXX;Initial Catalog=MyCtlg;Package 
     Collection=MyPkgCol;Default Schema=Schema;User ID=MyUser;Password=MyPW" 
   II.APPC:
     "Provider=DB2OLEDB;APPC Local LU Alias=MyAlias;APPC Remote LU 
     Alias=MyRemote;Initial Catalog=MyCtlg;Package Collection=MyPkgCol;Default 
     Schema=Schema;User ID=MyUser;Password=MyPW"  
7.Sybase 
  A.ODBC 
   I.Standard Sybase System 12 (or 12.5) Enterprise Open Client:
     "Driver={SYBASE ASE ODBC Driver};Srvr=Aron1;Uid=username;Pwd=password" 
   II.Standard Sybase System 11:
     "Driver={SYBASE SYSTEM 11};Srvr=Aron1;Uid=username;Pwd=password;" 
   III.Intersolv 3.10:
     "Driver={INTERSOLV 3.10 32-BIT Sybase};Srvr=Aron1;Uid=username;
     Pwd=password;" 
   IIII.Sybase SQL Anywhere (former Watcom SQL ODBC driver):
    "ODBC; Driver=Sybase SQL Anywhere 5.0; DefaultDir=c:\dbfolder\;Dbf=
    c:\mydatabase.db;Uid=username;Pwd=password;Dsn=""""" 
  B.OLEDB
    I.Adaptive Server Anywhere (ASA):
    "Provider=ASAProv;Data source=myASA" 
    II.Adaptive Server Enterprise (ASE) with Data Source .IDS file:
    "Provider=Sybase ASE OLE DB Provider; Data source=myASE" 
    注:必须先用Data Administrator创徏Data Source .IDS file  
    III.Adaptive Server Enterprise (ASE):
    "Provider=Sybase.ASEOLEDBProvider;Srvr=myASEserver,5000;Catalog=myDBname;
    User Id=username;Password=password" 
8.Informix 
  A.ODBC 
    I.Informix 3.30:
    "Dsn=’?Driver={INFORMIX 3.30 32 BIT};Host=hostname;Server=myserver;Service=
    service-name;Protocol=olsoctcp;Database=mydb;UID=username;PWD=myPwd 
    II.Informix-CLI 2.5:
    "Driver={Informix-CLI 2.5 (32 Bit)};Server=myserver;Database=mydb;
    Uid=username;Pwd=myPwd" 
  B.OLE DB 
    I.IBM Informix OLE DB Provider:
    "Provider=Ifxoledbc.2;password=myPw;User ID=myUser;Data Source=
    dbName@serverName;Persist Security Info=true" 
9.Mimer SQL 
  A.ODBC 
    I.Standard Security:
    "Driver={MIMER};Database=mydb;Uid=myuser;Pwd=mypw;" 
    II. Prompt for username and password:
    "Driver={MIMER};Database=mydb;" 
10.DSN 
  A.ODBC 
   I.DSN:
    "DSN=myDsn;Uid=username;Pwd=;" 
   II.File DSN:
    "FILEDSN=c:\myData.dsn;Uid=username;Pwd=;" 
11.Excel 
  A.ODBC 
   I.Standard:
    "Driver={Microsoft Excel Driver (*.xls)};DriverId=790;
    Dbq=C:\MyExcel.xls;DefaultDir=c:\mypath;" 
  B.OLE DB 
   I.Standard:
    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended 
    Properties=""Excel 8.0;HDR=Yes;IMEX=1""" 
    "HDR=Yes;" indicates that the first row contains columnnames, not data.
    "IMEX=1;" tells the driver to always read "intermixed" data columns as text.
12.Text 
  A.ODBC 
   I.Standard:
   "Driver={Microsoft Text Driver (*.txt; *.csv)};
   Dbq=c:\txtFilesFolder\;Extensions=asc,csv,tab,txt;" 
  B.OLE DB 
   I.Standard:
   "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\txtFilesFolder\;Extended 
   Properties=""text;HDR=Yes;FMT=Delimited""" 
   "HDR=Yes;" indicates that the first row contains columnnames, not data.
13.DBF / FoxPro 
  A.ODBC 
   I.standard:
   "Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=c:\mydbpath;" 
  B.OLE DB, OleDbConnection (.NET) 
   I.standard:
   "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\folder;Extended Properties=
   dBASE IV;User ID=Admin;Password="
14.Visual FoxPro 
  A.OLE DB, OleDbConnection (.NET) 
   I.Database container (.DBC):
   "Provider=vfpoledb.1;Data Source=C:\MyDbFolder\MyDbContainer.dbc;
   Password=MyPassWord;Collating Sequence=machine" 
   II. Free table directory:
   "Provider=vfpoledb.1;Data Source=C:\MyDataDirectory\;Password=MyPassWord;
   Collating Sequence=general" 
  B.ODBC 
   I.Database container (.DBC):
   "Driver={Microsoft Visual FoxPro Driver};SourceType=DBC;SourceDB=
   c:\myvfpdb.dbc;Exclusive=No;Collate=Machine;" 
   II.Free Table directory:
   "Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=
   c:\myvfpdbfolder;Exclusive=No;Collate=Machine;" 
15.Pervasive (没听说过q个东东)
  A.ODBC 
   I.Standard:
   "Driver={Pervasive ODBC Client Interface};ServerName=srvname;dbq=@dbname" 
  B.OLE DB 
   I.Standard:
   "Provider=PervasiveOLEDB;Data Source=C:\path" 
16.UDL 
   "File Name=c:\myDataLink.udl;"

]]>
利用UDL文g来徏立ADOq接http://www.shnenglu.com/ivenher/articles/1007.html爱饭?/dc:creator>爱饭?/author>Wed, 09 Nov 2005 07:04:00 GMThttp://www.shnenglu.com/ivenher/articles/1007.htmlhttp://www.shnenglu.com/ivenher/comments/1007.htmlhttp://www.shnenglu.com/ivenher/articles/1007.html#Feedback0http://www.shnenglu.com/ivenher/comments/commentRss/1007.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/1007.html
使用通用数据q接文gQ?.UDLQ以下简U文Ӟ来创建ADOq接Q可以和ODBC一样可视化地定义要q接的数据源Q从而实现数据访问的透明性?

   1.使用UDL文g来创建ADOq接

   创徏ADO的连接,首先要设|ADOq接对象的ConnectionString属性,该属性提供所要连接的数据库类型、数据所处服务器、要讉K的数据库和数据库讉K的安全认证信息。比较专业的Ҏ是在ConnectionString中直接提供以上信息,下面是访问不同类型数据源讄ConnectionString的标准:
讉KODBC数据

"Provider=MSDASQL;DSN=dsnName;UID=userName;PWD=userPassword;"
讉KORACLE数据?
"Provider=MSDAORA;Data Source=serverName;User ID=userName; Password=userPassword;"
讉KMS SQL数据?
"Provider=SQLOLEDB;Data Source=serverName;Initial Catalog=databaseName; User ID=userName;Password=userPassword;"
讉KACCESS 数据?
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=databaseName;User ID=userName;Password=userPassword;"

   上述的连接属性设|标准随着数据源的cd不同而变化,软g用户常常不习惯这U设|方式,都希望有可视化的数据源设|方法。ؓ此Microsoft提供了通用数据q接文gQ?UDLQ来建立和测试ADOq接属性。ADOq接对象可以很方便地使用UDL文g来连接数据源Q下面例子用my_data1.udl来创建ADOq接?

_ConnectionPtr m_pDBConn;
m_pDBConn.CreateInstance(__uuidof(Connection));
m_pDBConn->ConnectionString ="File Name=c:\mydir\my_data1.udl";  //注意Qname=cQ等号两边不能有I格
m_pDBConn->Open("","","",NULL);

   q样一来无论数据源如何变化Q在软g中都可以用统一的方法编E。当数据源改变时Q只要双ȝ应的udl文g卛_可视化地讄数据源,无需更改软g?

   因ؓADO是COM接口Qؓ了Y件的可靠性,打开ADOq接Ӟ可以加入异常处理代码?

try{
m_pDBConn->Open("","","",NULL);
}catch(_com_error &e){
//处理异常的代?
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
m_pDBConn=NULL;
}

   因ؓ_ConnectionPtr m_pDBConn是智能指针,应在处理异常代码时将指针设ؓNULL后将自动引用计数降??

   如果不出现异常,只要在用完m_pDBConnQ只要引用CloseҎ卛_?

   2.创徏你所需的UDL文g

   在你所惛_建UDL文g的目录中单击右键Q选择从菜?新徏|Microsoft 数据q接Q然后将新创建的UDL文g更改Z所希望的文件名Q?UDL扩展名不能改变)?



]]>
在Visual C++中用ADOq行数据库编E?http://www.shnenglu.com/ivenher/articles/992.html爱饭?/dc:creator>爱饭?/author>Wed, 09 Nov 2005 02:49:00 GMThttp://www.shnenglu.com/ivenher/articles/992.htmlhttp://www.shnenglu.com/ivenher/comments/992.htmlhttp://www.shnenglu.com/ivenher/articles/992.html#Feedback0http://www.shnenglu.com/ivenher/comments/commentRss/992.htmlhttp://www.shnenglu.com/ivenher/services/trackbacks/992.html



 


 1. 生成应用E序框架q初始化OLE/COM库环?

  创徏一个标准的MFC AppWizard(exe)应用E序Q然后在使用ADO数据?/A>的InitInstance函数中初始化OLE/COM库(因ؓADO库是一个COM DLL库)?BR>本例为:
 BOOL CAdotestDlg::OnInitDialog()
 {
        ::CoInitialize(NULL); //初始化OLE/COM库环?
  } 
E序最后要调用 ::CoUninitialize()Q?/释放E序占用的COM 资源?BR>另外Q?/TD>
m_pRecordset->Close(); 注意Q!Q不要多ơ关闭!Q!Q!Q!Q!Q!Q?
m_pConnection->Close();
m_pRecordset = NULL;
m_pConnection = NULL; 
 2. 引入ADO?A target=_blank>文g

  使用ADO前必d工程的stdafx.h文g最后用直接引入W号Qimport引入ADO?A target=_blank>文gQ以使编译器能正编译。代码如下:
#import "C:\Program Files\common files\system\ado\msado15.dll" no_namespace rename("EOF","adoEOF")
   ADOcȝ定义是作ZU资源存储在ADO DLL(msado15.dllQ中Q在其内部称为类型库。类型库描述了自L口,以及CQ+使用的COM vtable接口。当使用Qimport指oӞ在运行时Visual CQ+需要从ADO DLL中读取这个类型库Qƈ以此创徏一lCQ+?A target=_blank>文g。这些头文gh.tli ?tlh扩展名,读者可以在目的目录下扑ֈq两?A target=_blank>文g。在CQ+E序代码中调用的ADOc要在这?A target=_blank>文g中定义?
   E序的第三行指示ADO对象不用名U空间。在有些应用E序中,׃应用E序中的对象与ADO中的对象之间可能会出现命名冲H,所以有必要使用名称I间。如果要使用名称I间Q则可把W三?A target=_blank>E序修改为: rename_namespace("AdoNS")。第四行代码ADO中的EOF(文gl束)更名为adoEOFQ以避免与定义了自己的EOF的其他库冲突?

 3Q利用智能指针进?A target=_blank>数据?/A>操作

  在CaboutDlg?A target=_blank>文g中定义两个ADO指针cd?q在对话框中加入一个ListCtrl?BR> 
 class CAdotestDlg : public CDialog
{
     _ConnectionPtr m_pConnection;
     _RecordsetPtr m_pRecordset;
   ClistCtrl m_List; 
     ......
}     
ADO库包含三个智能指?_ConnectionPtr、_CommandPtr和_RecordsetPtr?BR>
_ConnectionPtr通常被用来创Z个数据连接或执行一条不q回Ml果的SQL语句Q如一个存储过E?BR>_CommandPtrq回一个记录集。它提供了一U简单的Ҏ来执行返回记录集的存储过E和SQL语句。在使用_CommandPtr接口Ӟ可以利用全局_ConnectionPtr接口Q也可以在_CommandPtr接口里直接用连接串。_RecordsetPtr是一个记录集对象。与以上两种对象相比Q它对记录集提供了更多的控制功能Q如记录锁定、游标控制等?

  在用ADOE序的事件响应中OnButton1加入以下代码:
 
void CAdotestDlg::OnButton1() 
{
	m_List.ResetContent();
	m_pConnection.CreateInstance(_uuidof(Connection)); //初始化Connection指针
	m_pRecordset.CreateInstance(_uuidof(Recordset));//初始化Recordset指针

	try
	{
		m_pConnection->Open("DSN=ADOTest","","",0); //q接叫作ADOTest的ODBC数据?
		//注意Q这是连接不需要用户ID或密码的open 函数
		// 否则形式?->Open("DSN=test;uid=sa;pwd=123;","","",0); 
	

		// 执行SQL语句得到一个记录集把其指针赋值给m_pRecordset
		CString strSql="select * from middle";
		BSTR bstrSQL = strSql.AllocSysString(); 
		m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
		//adOpenDynamicQ动?adLockOptimistic乐观锁?adCmdTextQ文本查询语?

		while(!m_pRecordset->adoEOF)//遍历所有记?
		{ 
			//取纪录字D值方式之一
			_variant_t TheValue; //VARIANT数据cd
			TheValue = m_pRecordset->GetCollect("BIG_NAME");//得到字段BIG_NAME的?
			if(TheValue.vt!=VT_NULL)
				m_List.AddString((char*)_bstr_t(TheValue));
			//该值加入到列表控g?
	
			//取纪录字D值方式之?
			// _bstr_t TheValue1=m_pRecordset->Fields->GetItem("BIG_NAME")->Value;
			// CString temp=TheValue1.copy();
			// m_List.AddString(temp);

			//数据cd转换
			_variant_t vUsername,vBirthday,vID,vOld;
			TRACE("id:%d,姓名:%s,q龄:%d,生日:%s\r\n",
			vID.lVal,(LPCTSTR)(_bstr_t)vUsername,vOld.lVal,(LPCTSTR)(_bstr_t)vBirthday);


			m_pRecordset->MoveNext();//转到下一条纪?
		}
		m_pRecordset->Close();
		m_pConnection->Close();
	}
	catch (_com_error e)//异常处理
	{
		AfxMessageBox(e.ErrorMessage());
	}
	m_pRecordset->Close(); //注意Q!Q不要多ơ关闭!Q!Q否则会出错
	m_pConnection->Close();
	m_pRecordset = NULL;
	m_pConnection = NULL; 
} 
  E序中通过_variant_t和_bstr_t转换COM对象和CQ+cd的数? _variant_tcd装了OLE自治VARIANT数据cd。在C++中用_variant_tc要比直接用VARIANT数据cdҎ得多?

  好,~译后该E序pq行了,但记住运行前要创Z个叫ADOTest的ODBC数据源。该E序把表middle中的BIG_NAME字段值显C在列表控g中?BR>


 4Q执行SQL命oq取得结果记录集

    Z取得l果记录集,我们定义一个指向Recordset对象的指?_RecordsetPtr m_pRecordset;
qؓ其创建Recordset对象的实? m_pRecordset.CreateInstance("ADODB.Recordset");
SQL命o的执行可以采用多UŞ式,下面我们一q行阐述?BR>
(1)利用Connection对象的ExecuteҎ执行SQL命o
ExecuteҎ的原型如下所C?
     _RecordsetPtr Connection15::Execute ( _bstr_t CommandText, VARIANT * RecordsAffected, long Options ) 
     其中CommandText是命令字Ԍ通常是SQL命o?

	参数RecordsAffected是操作完成后所影响的行? 

	参数Options表示CommandText中内容的cdQOptions可以取如下g一Q?
	adCmdText:表明CommandText是文本命?
	adCmdTable:表明CommandText是一个表?
	adCmdProc:表明CommandText是一个存储过E?
	adCmdUnknown:未知

    Execute执行完后q回一个指向记录集的指针,下面我们l出具体代码q作说明?
    _variant_t RecordsAffected;
    ///执行SQL命oQCREATE TABLE创徏表格users,users包含四个字段:整ŞID,字符串username,整Şold,日期型birthday
    m_pConnection->Execute("CREATE TABLE users(ID INTEGER,username TEXT,old INTEGER,birthday DATETIME)",
			&RecordsAffected,
			adCmdText);
    ///往表格里面d记录
    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);
    ///执行SQLl计命o得到包含记录条数的记录集
    m_pRecordset =  m_pConnection->Execute("SELECT COUNT(*) FROM users",&RecordsAffected,adCmdText);
    _variant_t vIndex = (long)0;
    _variant_t vCount = m_pRecordset->GetCollect(vIndex);///取得W一个字D늚值放入vCount变量
    上两句可以写成?_variant_t vCount = m_pRecordset->GetCollect((_variant_t)((long)0));
    m_pRecordset->Close();///关闭记录?
    CString message;
    message.Format("共有%d条记?,vCount.lVal);
    AfxMessageBox(message);///昄当前记录条数
(2)利用Command对象来执行SQL命o
_CommandPtr m_pCommand;
m_pCommand.CreateInstance("ADODB.Command");
_variant_t vNULL;
vNULL.vt = VT_ERROR;
vNULL.scode = DISP_E_PARAMNOTFOUND;///定义为无参数
m_pCommand->ActiveConnection = m_pConnection;///非常关键的一句,徏立的q接赋值给?
m_pCommand->CommandText = "SELECT * FROM users";///命o字串
m_pRecordset = m_pCommand->Execute(&vNULL,&vNULL,adCmdText);///执行命oQ取得记录集
    在这D代码中我们只是用Command对象来执行了SELECT查询语句QCommand对象在进行存储过E的调用中能真正体现它的作用。下ơ我们将详细介绍?

(3)直接用Recordset对象q行查询取得记录?
实例—?/TD>
void CGmsaDlg::OnDBSelect() 
{
    // TODO: Add your control notification handler code here
     _RecordsetPtr Rs1;  //定义Recordset对象
    _bstr_t Connect("DSN=GMS;UID=sa;PWD=;");//定义q接字符?
    _bstr_t Source ("SELECT count(*) FROM buaa.mdb010");  //要执行的SQL语句
    ::CoInitialize(NULL);    //初始化Rs1对象
        HRESUL hr = Rs1.CreateInstance( __uuidof( Recordset ) );
       //省略对返回值hr的判?
     Rs1->Open( Source,
            Connect,
                adOpenForwardOnly,
                    adLockReadOnly,
            -1 ); 
    _variant_t temp=Rs1->GetCollect(_variant_t((long)0));
    CString strTemp=(char* )(_bstr_t)temp;
    MessageBox("OK!"+strTemp);
}

例如 

  m_pRecordset->Open("SELECT * FROM users",
		_variant_t((IDispatch *)m_pConnection,true),
		adOpenStatic,
		adLockOptimistic,
		adCmdText);

OpenҎ的原型是q样?
HRESULT Recordset15::Open ( const _variant_t & Source, 
			const _variant_t & ActiveConnection, 
			enum CursorTypeEnum CursorType, 
			enum LockTypeEnum LockType, 
			long Options ) 
其中Q?
①Source是数据查?A  target=_blank>字符?
②ActiveConnection是已l徏立好的连接(我们需要用Connection对象指针来构造一个_variant_t对象) 
③CursorType光标cdQ它可以是以下g一,Lq个枚Dl构:
enum CursorTypeEnum
{
	adOpenUnspecified = -1,///不作特别指定
	adOpenForwardOnly = 0,///前滚静态光标。这U光标只能向前浏览记录集Q比如用MoveNext向前滚动,q种方式可以提高览速度。但诸如BookMark,RecordCount,AbsolutePosition,AbsolutePage都不能?
	adOpenKeyset = 1,///采用q种光标的记录集看不到其它用L新增、删除操作,但对于更新原有记录的操作对你是可见的?
	adOpenDynamic = 2,///动态光标。所?A  target=_blank>数据?/A>的操作都会立卛_各用戯录集上反应出来?
	adOpenStatic = 3///静态光标。它Z的记录集产生一个静态备份,但其它用L新增、删除、更新操作对你的记录集来说是不可见的?
};
④LockType锁定cdQ它可以是以下g一Q请看如下枚丄构:
enum LockTypeEnum
{
	adLockUnspecified = -1,///未指?
	adLockReadOnly = 1,///只读记录?
	adLockPessimistic = 2,悲观锁定方式。数据在更新旉定其它所有动作,q是最安全的锁定机?
	adLockOptimistic = 3,乐观锁定方式。只有在你调用UpdateҎ时才锁定记录。在此之前仍然可以做数据的更新、插入、删除等动作
	adLockBatchOptimistic = 4Q乐观分Ҏ新。编辑时记录不会锁定Q更攏V插入及删除是在批处理模式下完成?
}; 
⑤Options可以取如下g一Q?
	adCmdText:表明CommandText是文本命?
	adCmdTable:表明CommandText是一个表?
	adCmdProc:表明CommandText是一个存储过E?
	adCmdUnknown:未知
 5. 记录集的遍历、更?BR>    Ҏ我们刚才通过执行SQL命o建立好的users表,它包含四个字D?ID,username,old,birthday
以下的代码实玎ͼ打开记录集,遍历所有记录,删除W一条记录,d三条记录Q移动光标到W二条记录,
更改其年龄,保存?A target=_blank>数据?/A>?/TD>
_variant_t vUsername,vBirthday,vID,vOld;
_RecordsetPtr m_pRecordset;
m_pRecordset.CreateInstance("ADODB.Recordset");
m_pRecordset->Open("SELECT * FROM users",
		_variant_t((IDispatch*)m_pConnection,true),
		adOpenStatic,
		adLockOptimistic,
		adCmdText);
while(!m_pRecordset->adoEOF)
{
    vID = m_pRecordset->GetCollect(_variant_t((long)0));///取得W?列的??开始计敎ͼ
    ///你也可以直接l出列的名称Q如下一?
    vUsername = m_pRecordset->GetCollect("username");///取得username字段的?
    vOld = m_pRecordset->GetCollect("old");
    vBirthday = m_pRecordset->GetCollect("birthday");
    ///在DEBUG方式下的OUTPUTH口输出记录集中的记?
    if(vID.vt != VT_NULL && vUsername.vt != VT_NULL && vOld.vt != VT_NULL && vBirthday.vt != VT_NULL)
        TRACE("id:%d,姓名:%s,q龄:%d,生日:%s\r\n",
		vID.lVal,
		(LPCTSTR)(_bstr_t)vUsername,
		vOld.lVal,
		(LPCTSTR)(_bstr_t)vBirthday);
    m_pRecordset->MoveNext();///Ud下一条记?
}
m_pRecordset->MoveFirst();///Ud首条记录
m_pRecordset->Delete(adAffectCurrent);///删除当前记录
///d三条新记录ƈ赋?
for(int i=0;i<3;i++)
{
    m_pRecordset->AddNew();///d新记?
    m_pRecordset->PutCollect("ID",_variant_t((long)(i+10)));
    m_pRecordset->PutCollect("username",_variant_t("叶利?));
    m_pRecordset->PutCollect("old",_variant_t((long)71));
    m_pRecordset->PutCollect("birthday",_variant_t("1930-3-15"));
}
m_pRecordset->Move(1,_variant_t((long)adBookmarkFirst));///从第一条记录往下移动一条记?即移动到W二条记录处
m_pRecordset->PutCollect(_variant_t("old"),_variant_t((long)45));///修改其年?
m_pRecordset->Update();///保存到库?   
备注Q多ơ查询可把查询过E做成一个函数ExecuteSQL让m_pRecordset获得q接指针m_pConnection查询l果
void ExecuteSQL(_ConnectionPtr  m_pConnection, _RecordsetPtr  m_pRecordset,CString strSql)
{
    //执行Select 语句
    BSTR bstrSQL = strSql.AllocSysString();           
     try
     {
        m_pRecordset->Open(bstrSQL,(IDispatch*)m_pConnection,adOpenDynamic,adLockOptimistic,adCmdText); 
            //adOpenDynamicQ动? adLockOptimistic乐观锁? adCmdTextQ文本查询语?

     }

     catch(_com_error error)
     {
        CString errorMessage;
        errorMessage.Format("%s",(LPTSTR)error.Description());
        AfxMessageBox(errorMessage);
     }
}        

//出错处理Q?
3127——没有找到目标表
3092——目标表已经存在
例如Q?
catch(const _com_error e)
{
     AfxMessageBox(e.Description());
     long errorCode=e.WCode();
     if(3127==errorCode) AfxMessageBox("表不存在");
     if(3092==errorCode) AfxMessageBox("表已l存?);
     return FALSE;
} 
    
 


]]>
ADOq接字符?/title><link>http://www.shnenglu.com/ivenher/articles/827.html</link><dc:creator>爱饭?/dc:creator><author>爱饭?/author><pubDate>Mon, 24 Oct 2005 08:19:00 GMT</pubDate><guid>http://www.shnenglu.com/ivenher/articles/827.html</guid><wfw:comment>http://www.shnenglu.com/ivenher/comments/827.html</wfw:comment><comments>http://www.shnenglu.com/ivenher/articles/827.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/ivenher/comments/commentRss/827.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/ivenher/services/trackbacks/827.html</trackback:ping><description><![CDATA[<div id="gkmg8w4" class=postTitle><A id=_f3879933b975fd50_HomePageDays_DaysList__ctl0_DayItem_DayList__ctl0_TitleUrl >www.connectionstrings.com</A> </DIV> <div id="m8uaom8" class=postText> <DIV><FONT size=2><span id="w6844qs" class=toplvl ondblclick=menu(sqlserver); style="CURSOR: hand" onclick=menu(sqlserver);><FONT face=Courier size=3> </FONT> <LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)"> SQL Server </SPAN> <UL><SPAN id=sqlserver><span id="ie4m8us" class=seclvl ondblclick=menu(sqlserverodbc); style="CURSOR: hand" onclick=menu(sqlserverodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)"> ODBC </SPAN><BR><BR><SPAN id=sqlserverodbc style="CURSOR: default"> <UL> <LI><B> Standard Security:</B><BR> <DIV>"Driver={SQL Server};Server=Aron1;Database=pubs;Uid=sa;Pwd=asdasd;" </DIV><BR><BR> <LI><B> Trusted connection:</B><BR> <DIV>"Driver={SQL Server};Server=Aron1;Database=pubs;Trusted_Connection=yes;" </DIV><BR><BR> <LI><B> Prompt for username and password:</B><BR> <DIV>oConn.Properties("Prompt") = adPromptAlways<BR>oConn.Open "Driver={SQL Server};Server=Aron1;DataBase=pubs;" </DIV><BR><BR></LI></UL></SPAN><span id="ceu84sa" class=seclvl ondblclick=menu(sqlserveroledb); style="CURSOR: hand" onclick=menu(sqlserveroledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)"> OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=sqlserveroledb style="CURSOR: default"> <UL> <LI><B> Standard Security:</B><BR> <DIV>"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;" </DIV><BR><BR> <LI><B> Trusted Connection:</B><BR> <DIV>"Provider=sqloledb;Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;" <BLOCKQUOTE><I>(use serverName\instanceName as Data Source to use an specifik SQLServer instance, only SQLServer2000)</I></BLOCKQUOTE></DIV> <LI><B> Prompt for username and password:</B><BR> <DIV>oConn.Provider = "sqloledb"<BR>oConn.Properties("Prompt") = adPromptAlways<BR>oConn.Open "Data Source=Aron1;Initial Catalog=pubs;" </DIV><BR><BR> <LI><B> Connect via an IP address:</B><BR> <DIV>"Provider=sqloledb;Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;" <BLOCKQUOTE><I>(DBMSSOCN=TCP/IP instead of Named Pipes, at the end of the Data Source is the port to use (1433 is the default))</I></BLOCKQUOTE></DIV></LI></UL></SPAN><span id="8c4g6k8" class=seclvl ondblclick=menu(sqlserveradonet); style="CURSOR: hand" onclick=menu(sqlserveradonet);> <LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)"> SqlConnection (.NET) </SPAN><BR><BR><SPAN id=sqlserveradonet style="CURSOR: default"> <UL> <LI><B> Standard Security:</B><BR> <DIV>"Data Source=Aron1;Initial Catalog=pubs;User Id=sa;Password=asdasd;" <BR><I>   - or -</I><BR>"Server=Aron1;Database=pubs;User ID=sa;Password=asdasd;Trusted_Connection=False" <BR><I>   (booth connection strings produces the same result)</I><BR></DIV><BR><BR> <LI><B> Trusted Connection:</B><BR> <DIV>"Data Source=Aron1;Initial Catalog=pubs;Integrated Security=SSPI;" <BR><I>   - or -</I><BR>"Server=Aron1;Database=pubs;Trusted_Connection=True;" <BR><I>   (booth connection strings produces the same result)</I><BR> <BLOCKQUOTE><I>(use serverName\instanceName as Data Source to use an specifik SQLServer instance, only SQLServer2000)</I></BLOCKQUOTE></DIV> <LI><B> Connect via an IP address:</B><BR> <DIV>"Data Source=190.190.200.100,1433;Network Library=DBMSSOCN;Initial Catalog=pubs;User ID=sa;Password=asdasd;" <BLOCKQUOTE><I>(DBMSSOCN=TCP/IP instead of Named Pipes, at the end of the Data Source is the port to use (1433 is the default))</I></BLOCKQUOTE></DIV> <LI><B> Declare the SqlConnection:</B><BR> <DIV> <BLOCKQUOTE><I><U>C#:</U><BR>using System.Data.SqlClient;<BR>SqlConnection oSQLConn = new SqlConnection();<BR>oSQLConn.ConnectionString="my connectionstring";<BR>oSQLConn.Open(); </BLOCKQUOTE></DIV><BR><BR><U>VB.NET:</U><BR>Imports System.Data.SqlClient<BR>Dim oSQLConn As SqlConnection = New SqlConnection()<BR>oSQLConn.ConnectionString="my connectionstring"<BR>oSQLConn.Open() <DIV></DIV><BR><BR></I> <BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><span id="wiu4aug" class=seclvl ondblclick=menu(sqlserverother); style="CURSOR: hand" onclick=menu(sqlserverother);> <LI style="LIST-STYLE-IMAGE: url(icon/iconsql.gif)"> Data Shape </SPAN><BR><BR><SPAN id=sqlserverother style="CURSOR: default"> <UL> <LI><B> MS Data Shape</B><BR>"Provider=MSDataShape;Data Provider=SQLOLEDB;Data Source=Aron1;Initial Catalog=pubs;User ID=sa;Password=asdasd;" <BLOCKQUOTE><I>Want to learn data shaping? Check out 4GuyfFromRolla's <A title=http://www.4guysfromrolla.com/webtech/092599-1.shtml >great article about Data Shaping >></A></I></BLOCKQUOTE></LI></UL></SPAN><span id="wisqou8" class=seclvl ondblclick=menu(sqlserverreadmore); style="CURSOR: hand" onclick=menu(sqlserverreadmore);> <LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)"> Read more </SPAN><BR><BR><SPAN id=sqlserverreadmore style="DISPLAY: none; CURSOR: default"> <UL><span id="48s4q84" class=seclvl ondblclick=menu(sqlserverreadmorenetprot); style="CURSOR: hand" onclick=menu(sqlserverreadmorenetprot);> <LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)"> How to define wich network protocol to use<BR><BR></SPAN><SPAN id=sqlserverreadmorenetprot style="DISPLAY: none; CURSOR: default"> <UL> <LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)"> <DIV>Example:<BR>"Provider=sqloledb;Data Source=190.190.200.100,1433;<B><U>Network Library=DBMSSOCN</U></B>;Initial Catalog=pubs;User ID=sa;Password=asdasd;" <BR><BR> <TABLE> <TBODY> <TR> <TD width=100><FONT size=0><B><U>Name</U></B></FONT></TD> <TD><FONT size=0><B><U>Network library</U></B></FONT></TD></TR> <TR> <TD><FONT size=0>dbnmpntw</FONT></TD> <TD><FONT size=0>Win32 Named Pipes</FONT></TD></TR> <TR> <TD><FONT size=0>dbmssocn</FONT></TD> <TD><FONT size=0>Win32 Winsock TCP/IP</FONT></TD></TR> <TR> <TD><FONT size=0>dbmsspxn</FONT></TD> <TD><FONT size=0>Win32 SPX/IPX</FONT></TD></TR> <TR> <TD><FONT size=0>dbmsvinn</FONT></TD> <TD><FONT size=0>Win32 Banyan Vines</FONT></TD></TR> <TR> <TD><FONT size=0>dbmsrpcn</FONT></TD> <TD><FONT size=0>Win32 Multi-Protocol (Windows RPC)</FONT></TD></TR></TBODY></TABLE><FONT size=0><BR><BR><B>Important note!</B> <BR>When connecting through the SQLOLEDB provider use the syntax <I><U>Network Library</U>=dbmssocn</I><BR>and when connecting through MSDASQL provider use the syntax <I><U>Network</U>=dbmssocn</I> <BR><BR></FONT></DIV></LI></UL></SPAN></LI></UL> <UL><span id="4miy44u" class=seclvl ondblclick=menu(sqlserverreadmoreallprops); style="CURSOR: hand" onclick=menu(sqlserverreadmoreallprops);> <LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)"> All SqlConnection connectionstring properties<BR><BR></SPAN><SPAN id=sqlserverreadmoreallprops style="DISPLAY: none; CURSOR: default"> <UL> <LI style="LIST-STYLE-IMAGE: url(icon/iconreadmore.gif)"> <DIV>This table shows all connectionstring properties for the ADO.NET SqlConnection object. Most of the properties are also used in ADO. All properties and descriptions is from msdn. <BR><BR> <TABLE class=normaltxt style="BORDER-COLLAPSE: collapse" borderColor=#aaaaaa cellSpacing=0 cellPadding=4 border=1> <TBODY> <TR vAlign=top bgColor=#cccccc> <TH>Name</TH> <TH>Default</TH> <TH>Description</TH></TR> <TR vAlign=top> <TD>Application Name</TD> <TD> </TD> <TD>The name of the application, or '.Net SqlClient Data Provider' if no application name is provided.</TD></TR> <TR vAlign=top> <TD>AttachDBFilename<BR>-or-<BR>extended properties<BR>-or-<BR>Initial File Name</TD> <TD> </TD> <TD>The name of the primary file, including the full path name, of an attachable database. The database name must be specified with the keyword 'database'.</TD></TR> <TR vAlign=top> <TD>Connect Timeout<BR>-or-<BR>Connection Timeout</TD> <TD>15</TD> <TD>The length of time (in seconds) to wait for a connection to the server before terminating the attempt and generating an error.</TD></TR> <TR vAlign=top> <TD>Connection Lifetime</TD> <TD>0</TD> <TD>When a connection is returned to the pool, its creation time is compared with the current time, and the connection is destroyed if that time span (in seconds) exceeds the value specified by connection lifetime. Useful in clustered configurations to force load balancing between a running server and a server just brought on-line.</TD></TR> <TR vAlign=top> <TD>Connection Reset</TD> <TD>'true'</TD> <TD>Determines whether the database connection is reset when being removed from the pool. Setting to 'false' avoids making an additional server round-trip when obtaining a connection, but the programmer must be aware that the connection state is not being reset.</TD></TR> <TR vAlign=top> <TD>Current Language</TD> <TD> </TD> <TD>The SQL Server Language record name.</TD></TR> <TR vAlign=top> <TD>Data Source<BR>-or-<BR>Server<BR>-or-<BR>Address<BR>-or-<BR>Addr<BR>-or-<BR>Network Address</TD> <TD> </TD> <TD>The name or network address of the instance of SQL Server to which to connect.</TD></TR> <TR vAlign=top> <TD>Enlist</TD> <TD>'true'</TD> <TD>When true, the pooler automatically enlists the connection in the creation thread's current transaction context.</TD></TR> <TR vAlign=top> <TD>Initial Catalog<BR>-or-<BR>Database</TD> <TD> </TD> <TD>The name of the database.</TD></TR> <TR vAlign=top> <TD>Integrated Security<BR>-or-<BR>Trusted_Connection</TD> <TD>'false'</TD> <TD>Whether the connection is to be a secure connection or not. Recognized values are 'true', 'false', and 'sspi', which is equivalent to 'true'.</TD></TR> <TR vAlign=top> <TD>Max Pool Size</TD> <TD>100</TD> <TD>The maximum number of connections allowed in the pool.</TD></TR> <TR vAlign=top> <TD>Min Pool Size</TD> <TD>0</TD> <TD>The minimum number of connections allowed in the pool.</TD></TR> <TR vAlign=top> <TD>Network Library<BR>-or-<BR>Net</TD> <TD>'dbmssocn'</TD> <TD>The network library used to establish a connection to an instance of SQL Server. Supported values include dbnmpntw (Named Pipes), dbmsrpcn (Multiprotocol), dbmsadsn (Apple Talk), dbmsgnet (VIA), dbmsipcn (Shared Memory) and dbmsspxn (IPX/SPX), and dbmssocn (TCP/IP). <BR>The corresponding network DLL must be installed on the system to which you connect. If you do not specify a network and you use a local server (for example, "." or "(local)"), shared memory is used.</TD></TR> <TR vAlign=top> <TD>Packet Size</TD> <TD>8192</TD> <TD>Size in bytes of the network packets used to communicate with an instance of SQL Server.</TD></TR> <TR vAlign=top> <TD>Password<BR>-or-<BR>Pwd</TD> <TD> </TD> <TD>The password for the SQL Server account logging on.</TD></TR> <TR vAlign=top> <TD>Persist Security Info</TD> <TD>'false'</TD> <TD>When set to 'false', security-sensitive information, such as the password, is not returned as part of the connection if the connection is open or has ever been in an open state. Resetting the connection string resets all connection string values including the password.</TD></TR> <TR vAlign=top> <TD>Pooling</TD> <TD>'true'</TD> <TD>When true, the SQLConnection object is drawn from the appropriate pool, or if necessary, is created and added to the appropriate pool.</TD></TR> <TR vAlign=top> <TD>User ID</TD> <TD> </TD> <TD>The SQL Server login account.</TD></TR> <TR vAlign=top> <TD>Workstation ID</TD> <TD>the local computer name</TD> <TD>The name of the workstation connecting to SQL Server.</TD></TR></TBODY></TABLE><FONT size=0><BR><BR><B>Note</B> <BR>Use ; to separate each property.<BR>If a name occurs more than once, the value from the last one in the connectionstring will be used.<BR>If you are building your connectionstring in your app using values from user input fields, make sure the user can't change the connectionstring by inserting an additional property with another value within the user value. </FONT></DIV></LI></UL></SPAN></LI></UL></SPAN></LI></UL></SPAN> <UL></UL><span id="88e844i" class=toplvl ondblclick=menu(access); style="CURSOR: hand" onclick=menu(access);> <LI style="LIST-STYLE-IMAGE: url(icon/iconaccess.gif)"> Access </SPAN> <UL><SPAN id=access><span id="48s4u44" class=seclvl ondblclick=menu(accessodbc); style="CURSOR: hand" onclick=menu(accessodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconaccess.gif)"> ODBC </SPAN><BR><BR><SPAN id=accessodbc style="CURSOR: default"> <UL> <LI><B> Standard Security:</B><BR> <DIV>"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;Uid=Admin;Pwd=;" </DIV><BR><BR> <LI><B> Workgroup:</B><BR> <DIV>"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;SystemDB=C:\mydatabase.mdw;" </DIV><BR><BR> <LI><B> Exclusive:</B><BR> <DIV>"Driver={Microsoft Access Driver (*.mdb)};Dbq=C:\mydatabase.mdb;Exclusive=1;Uid=admin;Pwd=" </DIV><BR><BR></LI></UL></SPAN><span id="moim4s4" class=seclvl ondblclick=menu(jetoledb); style="CURSOR: hand" onclick=menu(jetoledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconaccess.gif)"> OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=jetoledb style="CURSOR: default"> <UL> <LI><B> Standard security:</B><BR> <DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;User Id=admin;Password=;" </DIV><BR><BR> <LI><B> Workgroup (system database):</B><BR> <DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;Jet OLEDB:System Database=system.mdw;" </DIV><BR><BR> <LI><B> With password:</B><BR> <DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\somepath\mydb.mdb;Jet OLEDB:Database Password=MyDbPassword;" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><span id="ak4ao4i" class=toplvl ondblclick=menu(oracle); style="CURSOR: hand" onclick=menu(oracle);> <LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)"> Oracle </SPAN> <UL><SPAN id=oracle><span id="8a44ceo" class=seclvl ondblclick=menu(oracleodbc); style="CURSOR: hand" onclick=menu(oracleodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)"> ODBC </SPAN><BR><BR><SPAN id=oracleodbc style="CURSOR: default"> <UL> <LI><B> New version:</B><BR> <DIV>"Driver={Microsoft ODBC for Oracle};Server=OracleServer.world;Uid=Username;Pwd=asdasd;" </DIV><BR><BR> <LI><B> Old version:</B><BR> <DIV>"Driver={Microsoft ODBC Driver for Oracle};ConnectString=OracleServer.world;Uid=myUsername;Pwd=myPassword;" </DIV><BR><BR></LI></UL></SPAN><span id="iicw8uc" class=seclvl ondblclick=menu(oracleoledb); style="CURSOR: hand" onclick=menu(oracleoledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)"> OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=oracleoledb style="CURSOR: default"> <UL> <LI><B> Standard security:</B><BR> <DIV>"Provider=msdaora;Data Source=MyOracleDB;User Id=UserName;Password=asdasd;" <BLOCKQUOTE><I>This one's from Microsoft, the following are from Oracle</I></BLOCKQUOTE></DIV> <LI><B> Standard Security:</B><BR> <DIV>"Provider=OraOLEDB.Oracle;Data Source=MyOracleDB;User Id=Username;Password=asdasd;" </DIV><BR><BR> <LI><B> Trusted Connection:</B><BR> <DIV>"Provider=OraOLEDB.Oracle;Data Source=MyOracleDB;OSAuthent=1;" </DIV><BR><BR></LI></UL></SPAN><span id="gg4us8y" class=seclvl ondblclick=menu(oracleadonet); style="CURSOR: hand" onclick=menu(oracleadonet);> <LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)"> OracleConnection (.NET) </SPAN><BR><BR><SPAN id=oracleadonet style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"Data Source=Oracle8i;Integrated Security=yes"; <BLOCKQUOTE><I>This one works only with Oracle 8i release 3 or later</I></BLOCKQUOTE></DIV> <LI><B> Declare the OracleConnection:</B><BR> <DIV> <BLOCKQUOTE><I><U>C#:</U><BR>using System.Data.OracleClient;<BR>OracleConnection oOracleConn = new OracleConnection();<BR>oOracleConn.ConnectionString = "my connectionstring";<BR>oOracleConn.Open(); </BLOCKQUOTE></DIV><BR><BR><U>VB.NET:</U><BR>Imports System.Data.OracleClient<BR>Dim oOracleConn As OracleConnection = New OracleConnection()<BR>oOracleConn.ConnectionString = "my connectionstring"<BR>oOracleConn.Open() <DIV></DIV><BR><BR></I> <BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><span id="g8gms4a" class=seclvl ondblclick=menu(oradirect); style="CURSOR: hand" onclick=menu(oradirect);> <LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)"> Core Labs OraDirect (.NET) </SPAN><BR><BR><SPAN id=oradirect style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR>"User ID=scott; Password=tiger; Host=ora; Pooling=true; Min Pool Size=0;Max Pool Size=100; Connection Lifetime=0" <BLOCKQUOTE>Read more at <I><A title=http://www.crlab.com/ >Core Lab</A> and the <A title=http://www.crlab.com/oranet/ >product page</A>.</I></BLOCKQUOTE></LI></UL></SPAN><span id="uq8844c" class=seclvl ondblclick=menu(oracleother); style="CURSOR: hand" onclick=menu(oracleother);> <LI style="LIST-STYLE-IMAGE: url(icon/iconoracle.gif)"> Data Shape </SPAN><BR><BR><SPAN id=oracleother style="CURSOR: default"> <UL> <LI><B> MS Data Shape:</B><BR>"Provider=MSDataShape.1;Persist Security Info=False;Data Provider=MSDAORA;Data Source=orac;user id=username;password=mypw" <BLOCKQUOTE><I>Want to learn data shaping? Check out 4GuyfFromRolla's <A title=http://www.4guysfromrolla.com/webtech/092599-1.shtml >great article about Data Shaping >></A></I></BLOCKQUOTE></LI></UL></SPAN></SPAN></LI></UL><span id="q8y4yqc" class=toplvl ondblclick=menu(mysql); style="CURSOR: hand" onclick=menu(mysql);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)"> MySQL </SPAN> <UL><SPAN id=mysql><span id="kmy8m8m" class=seclvl ondblclick=menu(mysqlodbc); style="CURSOR: hand" onclick=menu(mysqlodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)"> ODBC </SPAN><BR><BR><SPAN id=mysqlodbc style="CURSOR: default"> <UL> <LI><B> Local database:</B><BR> <DIV>"Driver={mySQL};Server=mySrvName;Option=16834;Database=mydatabase;" </DIV><BR><BR> <LI><B> Remote database:</B><BR> <DIV>"Driver={mySQL};Server=data.domain.com;Port=3306;Option=131072;Stmt=;Database=my-database;Uid=username;Pwd=password;" </DIV><BR><BR></LI></UL></SPAN><span id="iime4u8" class=seclvl ondblclick=menu(mysqloledb); style="CURSOR: hand" onclick=menu(mysqloledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)"> OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=mysqloledb style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"Provider=MySQLProv;Data Source=mydb;User Id=UserName;Password=asdasd;" </DIV></LI></UL></SPAN><span id="uuwiou4" class=seclvl ondblclick=menu(mysqladonet); style="CURSOR: hand" onclick=menu(mysqladonet);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)"> MySqlConnection (.NET) </SPAN><BR><BR><SPAN id=mysqladonet style="CURSOR: default"> <UL> <LI><B> eInfoDesigns.dbProvider:</B><BR> <DIV>"Data Source=server;Database=mydb;User ID=username;Password=pwd;Command Logging=false" <BLOCKQUOTE><I>This one is used with <A title=http://www.einfodesigns.com/ >eInfoDesigns</A> dbProvider, an add-on to .NET</I></BLOCKQUOTE></DIV> <LI><B> Declare the MySqlConnection:</B><BR> <DIV> <BLOCKQUOTE><I><U>C#:</U><BR>using eInfoDesigns.dbProvider.MySqlClient;<BR>MySqlConnection oMySqlConn = new MySqlConnection();<BR>oMySqlConn.ConnectionString = "my connectionstring";<BR>oMySqlConn.Open(); </BLOCKQUOTE></DIV><BR><BR><U>VB.NET:</U><BR>Imports eInfoDesigns.dbProvider.MySqlClient<BR>Dim oMySqlConn As MySqlConnection = New MySqlConnection()<BR>oMySqlConn.ConnectionString = "my connectionstring"<BR>oMySqlConn.Open() <DIV></DIV><BR><BR></I> <BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><span id="qoacsy8" class=seclvl ondblclick=menu(mysqlclient); style="CURSOR: hand" onclick=menu(mysqlclient);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)"> SevenObjects MySqlClient (.NET) </SPAN><BR><BR><SPAN id=mysqlclient style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"Host=server; UserName=myusername; Password=mypassword;Database=mydb;" <BLOCKQUOTE><I>This is a freeware ADO.Net data provider from <A title=http://www.sevenobjects.com/ >SevenObjects</A></I></BLOCKQUOTE></DIV></LI></UL></SPAN><span id="om8u48e" class=seclvl ondblclick=menu(mysqldirect); style="CURSOR: hand" onclick=menu(mysqldirect);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmysql.gif)"> Core Labs MySQLDirect (.NET) </SPAN><BR><BR><SPAN id=mysqldirect style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"User ID=root; Password=pwd; Host=localhost; Port=3306; Database=test;Direct=true; Protocol=TCP; Compress=false; Pooling=true; Min Pool Size=0;Max Pool Size=100; Connection Lifetime=0" <BLOCKQUOTE>Read more at <I><A title=http://www.crlab.com/ >Core Lab</A> and the <A title=http://www.crlab.com/mysqlnet/ >product page</A>.</I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><span id="wuysgog" class=toplvl ondblclick=menu(interbase); style="CURSOR: hand" onclick=menu(interbase);> <LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)"> Interbase </SPAN> <UL><SPAN id=interbase><span id="omok4w8" class=seclvl ondblclick=menu(interbaseeasysoft); style="CURSOR: hand" onclick=menu(interbaseeasysoft);> <LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)"> ODBC, Easysoft </SPAN><BR><BR><SPAN id=interbaseeasysoft style="CURSOR: default"> <UL> <LI><B> Local computer:</B><BR> <DIV>"Driver={Easysoft IB6 ODBC};Server=localhost;Database=localhost:C:\mydatabase.gdb;Uid=username;Pwd=password" </DIV><BR><BR> <LI><B> Remote Computer:</B><BR> <DIV>"Driver={Easysoft IB6 ODBC};Server=ComputerName;Database=ComputerName:C:\mydatabase.gdb;Uid=username;Pwd=password" <BLOCKQUOTE><I>Read more about this driver: <A title=http://www.easysoft.com/products/2201/ >Easysoft ODBC-Interbase driver >></A><BR></I></BLOCKQUOTE></DIV></LI></UL></SPAN><span id="844eio4" class=seclvl ondblclick=menu(interbaseintersolv); style="CURSOR: hand" onclick=menu(interbaseintersolv);> <LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)"> ODBC, Intersolv </SPAN><BR><BR><SPAN id=interbaseintersolv style="CURSOR: default"> <UL> <LI><B> Local computer:</B><BR> <DIV>"Driver={INTERSOLV InterBase ODBC Driver (*.gdb)};Server=localhost;Database=localhost:C:\mydatabase.gdb;Uid=username;Pwd=password" </DIV><BR><BR> <LI><B> Remote Computer:</B><BR> <DIV>"Driver={INTERSOLV InterBase ODBC Driver (*.gdb)};Server=ComputerName;Database=ComputerName:C:\mydatabase.gdb;Uid=username;Pwd=password" <BLOCKQUOTE><I>This driver are provided by <A title=http://www.datadirect-technologies.com/ >DataDirect Technologies >></A> (formerly Intersolv) </I></BLOCKQUOTE></DIV><BR><BR></LI></UL></SPAN><span id="yq88uw8" class=seclvl ondblclick=menu(interbasesibprovider); style="CURSOR: hand" onclick=menu(interbasesibprovider);> <LI style="LIST-STYLE-IMAGE: url(icon/iconinterbase.gif)"> OLE DB, SIBPROvider </SPAN><BR><BR><SPAN id=interbasesibprovider style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"provider=sibprovider;location=localhost:;data source=c:\databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey" </DIV><BR><BR> <LI><B> Specifying character set:</B><BR> <DIV>"provider=sibprovider;location=localhost:;data source=c:\databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey;character set=ISO8859_1" </DIV><BR><BR> <LI><B> Specifying role:</B><BR> <DIV>"provider=sibprovider;location=localhost:;data source=c:\databases\gdbs\mygdb.gdb;user id=SYSDBA;password=masterkey;role=DIGITADORES" <BLOCKQUOTE><I><A title=http://www.sibprovider.com/en_us/default.asp >Read more about SIBPROvider >></A> </I></BLOCKQUOTE></DIV><BR><BR></LI></UL></SPAN><BR><I>Read more about connecting to Interbase in this Borland Developer Network article <A title=http://community.borland.com/article/0,1410,27152,00.html >http://community.borland.com/article/0,1410,27152,00.html</A> </I><BR><BR></SPAN></LI></UL><span id="cami448" class=toplvl ondblclick=menu(db2); style="CURSOR: hand" onclick=menu(db2);> <LI style="LIST-STYLE-IMAGE: url(icon/icondb2.gif)"> IBM DB2 </SPAN> <UL><SPAN id=db2><span id="syce4mw" class=seclvl ondblclick=menu(db2oledb); style="CURSOR: hand" onclick=menu(db2oledb);> <LI style="LIST-STYLE-IMAGE: url(icon/icondb2.gif)"> OLE DB, OleDbConnection (.NET) from ms </SPAN><BR><BR><SPAN id=db2oledb style="CURSOR: default"> <UL> <LI><B> TCP/IP:</B><BR> <DIV>"Provider=DB2OLEDB;Network Transport Library=TCPIP;Network Address=XXX.XXX.XXX.XXX;Initial Catalog=MyCtlg;Package Collection=MyPkgCol;Default Schema=Schema;User ID=MyUser;Password=MyPW" </DIV><BR><BR> <LI><B> APPC:</B><BR> <DIV>"Provider=DB2OLEDB;APPC Local LU Alias=MyAlias;APPC Remote LU Alias=MyRemote;Initial Catalog=MyCtlg;Package Collection=MyPkgCol;Default Schema=Schema;User ID=MyUser;Password=MyPW" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><span id="8o8wi44" class=toplvl ondblclick=menu(sybase); style="CURSOR: hand" onclick=menu(sybase);> <LI style="LIST-STYLE-IMAGE: url(icon/iconsybase.gif)"> Sybase </SPAN> <UL><SPAN id=sybase><span id="cse8ksu" class=seclvl ondblclick=menu(sybaseodbc); style="CURSOR: hand" onclick=menu(sybaseodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconsybase.gif)"> ODBC </SPAN><BR><BR><SPAN id=sybaseodbc style="CURSOR: default"> <UL> <LI><B> Standard Sybase System 12 (or 12.5) Enterprise Open Client:</B><BR> <DIV>"Driver={SYBASE ASE ODBC Driver};Srvr=Aron1;Uid=username;Pwd=password" </DIV><BR><BR> <LI><B> Standard Sybase System 11:</B><BR> <DIV>"Driver={SYBASE SYSTEM 11};Srvr=Aron1;Uid=username;Pwd=password;" <BLOCKQUOTE><I>Do you know a userguide for Sybase System 11, 12, 12.5? <A title=mailto:info@connectionstrings.com href="mailto:info@connectionstrings.com">E-mail the URL to connectionstrings.com now!! >> </A></I></BLOCKQUOTE></DIV> <LI><B> Intersolv 3.10:</B><BR> <DIV>"Driver={INTERSOLV 3.10 32-BIT Sybase};Srvr=Aron1;Uid=username;Pwd=password;" </DIV><BR><BR> <LI><B> Sybase SQL Anywhere (former Watcom SQL ODBC driver):</B><BR> <DIV>"ODBC; Driver=Sybase SQL Anywhere 5.0; DefaultDir=c:\dbfolder\;Dbf=c:\mydatabase.db;Uid=username;Pwd=password;Dsn=""""" <BLOCKQUOTE><I>Note! The two double quota following the DSN parameter at the end are escaped quotas (VB syntax), you may have to change this to your language specific escape syntax. The empty DSN parameter is indeed critical as not including it will result in error 7778. </BLOCKQUOTE></DIV><BR><BR><A title=http://manuals.sybase.com/onlinebooks/group-im/imcore5/conndb/@Generic__BookView/3404;cs=default;ts=default >Read more in the Sybase SQL Anywhere User Guide >></A> </I> <BLOCKQUOTE></BLOCKQUOTE></LI></UL></SPAN><span id="uk4ya88" class=seclvl ondblclick=menu(sybaseoledb); style="CURSOR: hand" onclick=menu(sybaseoledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconsybase.gif)"> OLE DB </SPAN><BR><BR><SPAN id=sybaseoledb style="CURSOR: default"> <UL> <LI><B> Adaptive Server Anywhere (ASA):</B><BR> <DIV>"Provider=ASAProv;Data source=myASA" <BLOCKQUOTE><I><A title=http://manuals.sybase.com/onlinebooks/group-sas/awg0702e/dbugen7/@ebt-link;pt=13894;uf=0?target=0;window=new;showtoc=true;book=dbugen7 >Read more in the ASA User Guide >></A> </I></BLOCKQUOTE></DIV> <LI><B> Adaptive Server Enterprise (ASE) with Data Source .IDS file:</B><BR> <DIV>"Provider=Sybase ASE OLE DB Provider; Data source=myASE" <BLOCKQUOTE><I>Note that you must create a Data Source .IDS file using the Sybase Data Administrator. These .IDS files resemble ODBC DSNs. </I></BLOCKQUOTE></DIV> <LI><B> Adaptive Server Enterprise (ASE):</B><BR> <DIV>"Provider=Sybase.ASEOLEDBProvider;Srvr=myASEserver,5000;Catalog=myDBname;User Id=username;Password=password" <BR><I>   - some reports on problem using the above one, try the following as an alternative -</I><BR><BR>"Provider=Sybase.ASEOLEDBProvider;Server Name=myASEserver,5000;Initial Catalog=myDBname;User Id=username;Password=password" <BLOCKQUOTE><I>This one works only from Open Client 12.5 where the server port number feature works,燼llowing fully qualified connection strings to be used without defining燼ny .IDS Data Source files. </I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><span id="cse8k84" class=toplvl ondblclick=menu(informix); style="CURSOR: hand" onclick=menu(informix);> <LI style="LIST-STYLE-IMAGE: url(icon/iconinformix.gif)"> Informix </SPAN> <UL><SPAN id=informix><span id="wo4agoq" class=seclvl ondblclick=menu(informixodbc); style="CURSOR: hand" onclick=menu(informixodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconinformix.gif)"> ODBC </SPAN><BR><BR><SPAN id=informixodbc style="CURSOR: default"> <UL> <LI><B> Informix 3.30:</B><BR> <DIV>"Dsn='';Driver={INFORMIX 3.30 32 BIT};Host=hostname;Server=myserver;Service=service-name;Protocol=olsoctcp;Database=mydb;UID=username;PWD=myPwd </DIV><BR><BR> <LI><B> Informix-CLI 2.5:</B><BR> <DIV>"Driver={Informix-CLI 2.5 (32 Bit)};Server=myserver;Database=mydb;Uid=username;Pwd=myPwd" </DIV><BR><BR></LI></UL></SPAN><span id="geq8wuw" class=seclvl ondblclick=menu(informixoledb); style="CURSOR: hand" onclick=menu(informixoledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconinformix.gif)"> OLE DB </SPAN><BR><BR><SPAN id=informixoledb style="CURSOR: default"> <UL> <LI><B> IBM Informix OLE DB Provider:</B><BR> <DIV>"Provider=Ifxoledbc.2;password=myPw;User ID=myUser;Data Source=dbName@serverName;Persist Security Info=true" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><span id="qg8444k" class=toplvl ondblclick=menu(mimer); style="CURSOR: hand" onclick=menu(mimer);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmimer.gif)"> Mimer SQL </SPAN> <UL><SPAN id=mimer><span id="ca4u8ss" class=seclvl ondblclick=menu(mimerodbc); style="CURSOR: hand" onclick=menu(mimerodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconmimer.gif)"> ODBC </SPAN><BR><BR><SPAN id=mimerodbc style="CURSOR: default"> <UL> <LI><B> Standard Security:</B><BR> <DIV>"Driver={MIMER};Database=mydb;Uid=myuser;Pwd=mypw;" </DIV><BR><BR> <LI><B> Prompt for username and password:</B><BR> <DIV>"Driver={MIMER};Database=mydb;" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><span id="884yuai" class=toplvl ondblclick=menu(postgre); style="CURSOR: hand" onclick=menu(postgre);> <LI style="LIST-STYLE-IMAGE: url(icon/iconpostgre.gif)"> PostgreSQL </SPAN> <UL><SPAN id=postgre><span id="ec84e8y" class=seclvl ondblclick=menu(postgresqldirect); style="CURSOR: hand" onclick=menu(postgresqldirect);> <LI style="LIST-STYLE-IMAGE: url(icon/iconpostgre.gif)"> Core Labs PostgreSQLDirect (.NET) </SPAN><BR><BR><SPAN id=postgresqldirect style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"User ID=root; Password=pwd; Host=localhost; Port=5432; Database=testdb;Pooling=true; Min Pool Size=0; Max Pool Size=100; Connection Lifetime=0" <BLOCKQUOTE>Read more at <I><A title=http://www.crlab.com/ >Core Lab</A> and the <A title=http://www.crlab.com/pgsqlnet/ >product page</A>.</I></BLOCKQUOTE></DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><span id="mco8sa4" class=toplvl ondblclick=menu(dsn); style="CURSOR: hand" onclick=menu(dsn);> <LI style="LIST-STYLE-IMAGE: url(icon/icondsn.gif)"> DSN </SPAN> <UL><SPAN id=dsn><span id="usc8oek" class=seclvl ondblclick=menu(dsnodbc); style="CURSOR: hand" onclick=menu(dsnodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/icondsn.gif)"> ODBC </SPAN><BR><BR><SPAN id=dsnodbc style="CURSOR: default"> <UL> <LI><B> DSN:</B><BR> <DIV>"DSN=myDsn;Uid=username;Pwd=;" </DIV><BR><BR> <LI><B> File DSN:</B><BR> <DIV>"FILEDSN=c:\myData.dsn;Uid=username;Pwd=;" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><span id="igig4w8" class=toplvl ondblclick=menu(excel); style="CURSOR: hand" onclick=menu(excel);> <LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)"> Excel </SPAN> <UL><SPAN id=excel><span id="8ywmk4u" class=seclvl ondblclick=menu(excelodbc); style="CURSOR: hand" onclick=menu(excelodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)"> ODBC </SPAN><BR><BR><SPAN id=excelodbc style="CURSOR: default"> <UL> <LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)"><B> Standard:</B><BR> <DIV>"Driver={Microsoft Excel Driver (*.xls)};DriverId=790;Dbq=C:\MyExcel.xls;DefaultDir=c:\mypath;" </DIV><BR><BR></LI></UL></SPAN><span id="4wc8e4e" class=seclvl ondblclick=menu(exceloledb); style="CURSOR: hand" onclick=menu(exceloledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)"> OLE DB </SPAN><BR><BR><SPAN id=exceloledb style="CURSOR: default"> <UL> <LI style="LIST-STYLE-IMAGE: url(icon/iconexcel.gif)"><B> Standard:</B><BR> <DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""</B>" <BLOCKQUOTE><I>"HDR=Yes;" indicates that the first row contains columnnames, not data</I></BLOCKQUOTE> <BLOCKQUOTE><I>"IMEX=1;" tells the driver to always read "intermixed" data columns as text</I></BLOCKQUOTE> <BLOCKQUOTE><I>TIP! SQL syntax: "SELECT * FROM [sheet1$]" - i.e. worksheet name followed by a "$" and wrapped in "[" "]" brackets.</I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><span id="igq8maq" class=toplvl ondblclick=menu(text); style="CURSOR: hand" onclick=menu(text);> <LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)"> Text </SPAN> <UL><SPAN id=text><span id="k48sm44" class=seclvl ondblclick=menu(textodbc); style="CURSOR: hand" onclick=menu(textodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)"> ODBC </SPAN><BR><BR><SPAN id=textodbc style="CURSOR: default"> <UL> <LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)"><B> Standard:</B><BR> <DIV>"Driver={Microsoft Text Driver (*.txt; *.csv)};Dbq=c:\txtFilesFolder\;Extensions=asc,csv,tab,txt;" </DIV><BR><BR></LI></UL></SPAN><span id="8komsqg" class=seclvl ondblclick=menu(textoledb); style="CURSOR: hand" onclick=menu(textoledb);> <LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)"> OLE DB </SPAN><BR><BR><SPAN id=textoledb style="CURSOR: default"> <UL> <LI style="LIST-STYLE-IMAGE: url(icon/icontext.gif)"><B> Standard:</B><BR> <DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\txtFilesFolder\;Extended Properties=""text;HDR=Yes;FMT=Delimited""" <BLOCKQUOTE><I>"HDR=Yes;" indicates that the first row contains columnnames, not data</I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><span id="q8g888m" class=toplvl ondblclick=menu(dbf); style="CURSOR: hand" onclick=menu(dbf);> <LI style="LIST-STYLE-IMAGE: url(icon/icondbf.gif)"> DBF / FoxPro </SPAN> <UL><SPAN id=dbf><span id="8y84k4g" class=seclvl ondblclick=menu(dbfodbc); style="CURSOR: hand" onclick=menu(dbfodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/icondbf.gif)"> ODBC </SPAN><BR><BR><SPAN id=dbfodbc style="CURSOR: default"> <UL> <LI><B> standard:</B><BR> <DIV>"Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq=c:\mydbpath;" </DIV><BR><BR></LI></UL></SPAN><span id="qwioes6" class=seclvl ondblclick=menu(dbfoledb); style="CURSOR: hand" onclick=menu(dbfoledb);> <LI style="LIST-STYLE-IMAGE: url(icon/icondbf.gif)"> OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=dbfoledb style="CURSOR: default"> <UL> <LI><B> standard:</B><BR> <DIV>"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\folder;Extended Properties=dBASE IV;User ID=Admin;Password=" </DIV><BR><BR></LI></UL></SPAN></SPAN></LI></UL><span id="k8sgwwe" class=toplvl ondblclick=menu(vfoxpro); style="CURSOR: hand" onclick=menu(vfoxpro);> <LI style="LIST-STYLE-IMAGE: url(icon/iconvfoxpro.gif)"> Visual FoxPro </SPAN> <UL><SPAN id=vfoxpro><span id="4am8ok4" class=seclvl ondblclick=menu(vfoxprooledb); style="CURSOR: hand" onclick=menu(vfoxprooledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconvfoxpro.gif)"> OLE DB, OleDbConnection (.NET) </SPAN><BR><BR><SPAN id=vfoxprooledb style="CURSOR: default"> <UL> <LI><B> Database container (.DBC):</B><BR> <DIV>"Provider=vfpoledb.1;Data Source=C:\MyDbFolder\MyDbContainer.dbc;Password=MyPassWord;Collating Sequence=machine" </DIV><BR><BR> <LI><B> Free table directory:</B><BR> <DIV>"Provider=vfpoledb.1;Data Source=C:\MyDataDirectory\;Password=MyPassWord;Collating Sequence=general" </DIV> <BLOCKQUOTE><A title=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fox7help/html/dggrfOLEDBProviderforVisualFoxPro.asp >Read more (Microsoft msdn) >></A></I></BLOCKQUOTE></LI></UL></SPAN><span id="csua8kq" class=seclvl ondblclick=menu(vfoxproodbc); style="CURSOR: hand" onclick=menu(vfoxproodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconvfoxpro.gif)"> ODBC </SPAN><BR><BR><SPAN id=vfoxproodbc style="CURSOR: default"> <UL> <LI><B> Database container (.DBC):</B><BR> <DIV>"Driver={Microsoft Visual FoxPro Driver};SourceType=DBC;SourceDB=c:\myvfpdb.dbc;Exclusive=No;Collate=Machine;" </DIV><BR><BR> <LI><B> Free Table directory:</B><BR> <DIV>"Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=c:\myvfpdbfolder;Exclusive=No;Collate=Machine;" <BLOCKQUOTE><I>"Collate=Machine" is the default setting, for other settings check the <A title=http://msdn.microsoft.com/library/default.asp?url=/library/en-us/odbc/htm/lr30b_11.asp >list of supported collating sequences >></A></I></BLOCKQUOTE></DIV></LI></UL></SPAN><BR><I>Microsoft Visual Foxpro site: <A title=http://msdn.microsoft.com/vfoxpro >http://msdn.microsoft.com/vfoxpro</A> </I><BR><BR></SPAN></LI></UL><span id="i8gua4s" class=toplvl ondblclick=menu(pervasive); style="CURSOR: hand" onclick=menu(pervasive);> <LI style="LIST-STYLE-IMAGE: url(icon/iconpervasive.gif)"> Pervasive </SPAN> <UL><SPAN id=pervasive><span id="cakgi84" class=seclvl ondblclick=menu(pervasiveodbc); style="CURSOR: hand" onclick=menu(pervasiveodbc);> <LI style="LIST-STYLE-IMAGE: url(icon/iconpervasive.gif)"> ODBC </SPAN><BR><BR><SPAN id=pervasiveodbc style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"Driver={Pervasive ODBC Client Interface};ServerName=srvname;dbq=@dbname" <BLOCKQUOTE><I><A title=http://www.pervasive.com/library/index.asp?_portal=ODBC >Pervasive ODBC info >></A></I></BLOCKQUOTE></DIV></LI></UL></SPAN><span id="i8qei44" class=seclvl ondblclick=menu(pervasiveoledb); style="CURSOR: hand" onclick=menu(pervasiveoledb);> <LI style="LIST-STYLE-IMAGE: url(icon/iconpervasive.gif)"> OLE DB </SPAN><BR><BR><SPAN id=pervasiveoledb style="CURSOR: default"> <UL> <LI><B> Standard:</B><BR> <DIV>"Provider=PervasiveOLEDB;Data Source=C:\path" <BLOCKQUOTE><I><A title=http://www.pervasive.com/library/index.asp?_portal=OLEDB >Pervasive OLE DB info >></A></I></BLOCKQUOTE></DIV></LI></UL></SPAN></SPAN></LI></UL><span id="884swu4" class=toplvl ondblclick=menu(udl); style="CURSOR: hand" onclick=menu(udl);> <LI style="LIST-STYLE-IMAGE: url(icon/iconudl.gif)"> UDL </SPAN> <UL><SPAN id=udl><span id="ukw8say" class=seclvl ondblclick=menu(udludl); style="CURSOR: hand" onclick=menu(udludl);> <LI style="LIST-STYLE-IMAGE: url(icon/iconudl.gif)"> UDL </SPAN><BR><BR><SPAN id=udludl style="CURSOR: default"> <UL> <LI><B> UDL:</B><BR> <DIV>"File Name=c:\myDataLink.udl;" </DIV></LI></UL></SPAN></SPAN></LI></UL></FONT></LI></DIV></DIV><img src ="http://www.shnenglu.com/ivenher/aggbug/827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/ivenher/" target="_blank">爱饭?/a> 2005-10-24 16:19 <a href="http://www.shnenglu.com/ivenher/articles/827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.touzhi8.cn" target="_blank">þþþþþƷ</a>| <a href="http://www.mmcase.cn" target="_blank">þۺɫ</a>| <a href="http://www.gnjb.net.cn" target="_blank">aѹۿþav</a>| <a href="http://www.4000261688.cn" target="_blank">պŷۺϾþ</a>| <a href="http://www.ndali.cn" target="_blank">ŷ˾þۺ</a>| <a href="http://www.javaoop.cn" target="_blank">ľþþþ</a>| <a href="http://www.gn-online.com.cn" target="_blank">ľƷ99þù</a>| <a href="http://www.i501.cn" target="_blank">Ʒþþþþ</a>| <a href="http://www.jiangkangcmw.cn" target="_blank">ŷ˾þô߽ۺ69</a>| <a href="http://www.seasa.cn" target="_blank">ݹƷþþþ</a>| <a href="http://www.lishuiqiao.cn" target="_blank">ھƷþþþù</a>| <a href="http://www.fly5.com.cn" target="_blank">Ʒ99þþƷ</a>| <a href="http://www.662z.cn" target="_blank">ƬҹƬþ</a>| <a href="http://www.rolanskin.cn" target="_blank">þ99Ʒþþþþò</a>| <a href="http://www.efd-inc.com.cn" target="_blank">99þֻоƷ</a>| <a href="http://www.lvomb.cn" target="_blank">޾ƷþþþĻ69 </a>| <a href="http://www.vnaiman.cn" target="_blank">ŷþþþƷ</a>| <a href="http://www.51kuyu.cn" target="_blank">þþƷ˵</a>| <a href="http://www.tjyizhao.cn" target="_blank">͵þþþƷר</a>| <a href="http://www.lpxiu.cn" target="_blank">þ޾Ʒa </a>| <a href="http://www.xecwf.cn" target="_blank">þþƷƷʢۿ</a>| <a href="http://www.ghbo.cn" target="_blank">þ99ֻƵƷ8</a>| <a href="http://www.rainbows.net.cn" target="_blank">þþþþùƷŮ</a>| <a href="http://www.ts71.cn" target="_blank">þþþùһëƬ</a>| <a href="http://www.rmbo.cn" target="_blank">þӰԺҹƬ</a>| <a href="http://www.22980000.cn" target="_blank">þˬ˸߳AV</a>| <a href="http://www.zhe38.cn" target="_blank">vvaþ</a>| <a href="http://www.bilili.com.cn" target="_blank">պƷרþþ</a>| <a href="http://www.rqhsjc.cn" target="_blank">㽶þҹɫƷ2020</a>| <a href="http://www.976z.cn" target="_blank">һһþaaۺϾƷ</a>| <a href="http://www.yyyart.cn" target="_blank">AVݺɫۺϾþ</a>| <a href="http://www.zuiaimama.cn" target="_blank">aaþ</a>| <a href="http://www.pbti.com.cn" target="_blank">þۺ¶þü</a>| <a href="http://www.bamboomart.cn" target="_blank">þþþþùƷŮ</a>| <a href="http://www.guidegogo.cn" target="_blank">þþþavרˮ </a>| <a href="http://www.chipsummit.cn" target="_blank">ݹ97þ÷ѹۿ</a>| <a href="http://www.moneychange.cn" target="_blank">þۺ϶</a>| <a href="http://www.enikl.cn" target="_blank">պƷþĻ</a>| <a href="http://www.bao00long.cn" target="_blank">ԭۺϾþ</a>| <a href="http://www.ctihf.com.cn" target="_blank">պݺݾþ͵͵ɫۺ </a>| <a href="http://www.shoescaps.cn" target="_blank">ݺݾþۺ˲</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>