5、修改数据
方法一:
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属性的值,即改变了字段的值。
方法二:
m_pRecordset->Fields->GetItem
(_variant_t("姓名"))->PutValue(_bstr_t("赵薇"));
方法三:就是用定义绑定类的方法(详见后面的介绍)。
6、添加记录
新记录添加成功后,即自动成为当前记录。AddNew方法有两种形式,一个含有参数,而另一个则不带参数。
方法一(不带参数):
// 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);
}
这种方法弄完了还要调用Update()。
方法二(带参数):
_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);
这种方法不需要调用Update,因为添加后,ADO会自动调用它。此方法主要是使用SafeArray挺麻烦。
方法三:就是用定义绑定类的方法(详见后面的介绍)。
7、删除记录
调用Recordset的Delete方法就行了,删除的是当前记录。要了解Delete的其它用法请查阅参考文献。
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删除她吗?", "提示",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、使用带参数的命令
Command对象所代表的就是一个Provider能够理解的命令,如SQL语句等。使用Command对象的关键就是把表示命令的语句设置到 CommandText属性中,然后调用Command对象的Execute方法就行了。一般情况下在命令中无需使用参数,但有时使用参数,可以增加其灵 活性和效率。
(1). 建立连接、命令对象和记录集对象
本例中表示命令的语句就是一个SQL语句(SELECT语句)。SELECT语句中的问号?就代表参数,如果要多个参数,就多放几个问号,每个问号代表一个参数。
_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
要注意命令对象必须与连接对象关联起来才能起作用,本例中将命令对象的ActiveConnection属性设置为连接对象的指针,即为此目的:
Cmd1->ActiveConnection = Conn1;
(2). 创建参数对象,并给参数赋值
// 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 );
用命令对象的方法来创建一个参数对象,其中的长度参数(第三个)如果是固定长度的类型,就填-1,如果是字符串等可变长度的就填其实际长度。 Parameters是命令对象的一个容器,它的Append方法就是把创建的参数对象追加到该容器里。Append进去的参数按先后顺序与SQL语句中 的问号从左至右一一对应。
(3). 执行命令打开记录集
// Open Recordset Object
Rs1 = Cmd1->Execute( &vtEmpty, &vtEmpty2, adCmdText );
但要注意,用Command和Connection对象的Execute方法得到的Recordset是只读的。因为在打开Recordset之前,我们无法设置它的LockType属性(其默认值为只读)。而在打开之后设置LockType不起作用。
我发现用上述方法得到记录集Rs1后,不但Rs1中的记录无法修改,即使直接用SQL语句修改同一表中任何记录都不行。
要想能修改数据,还是要用Recordset自己的Open方法才行,如:
try{
m_pRecordset->Open((IDispatch *) Cmd1, vtMissing, adOpenStatic, adLockOptimistic, adCmdUnspecified);
}
catch (_com_error &e)
{
::MessageBox(NULL,"mytable表不存在。","提示",MB_OK │ MB_ICONWARNING);
}
Recordset对象的Open方法真是太好了,其第一个参数可以是SQL语句、表名字、命令对象指针等等。