现在的位置: 首页 > 综合 > 正文

Visual C++ ADO数据库编程入门(2)

2014年01月29日 ⁄ 综合 ⁄ 共 4593字 ⁄ 字号 评论关闭

 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语句、表名字、命令对象指针等等。

抱歉!评论已关闭.