无论是在odbc数据源处还是在access表处都没设置“只读”属性,
但程序一旦对表进行修改等操作时,总提示记录集是只读的,why!!!

解决方案 »

  1.   

    你在open的时候参数设置对了吗?好好看看。
      

  2.   

    我是初学这个做课程设计,只建了一张表,
    我那本书上m_pSet->Open()好象没写什么参数,
    不知道还有什么细节,望大家指教。
      

  3.   

    Open 的参数有缺省值, 下面是msdn里的摘录
    virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, LPCTSTR lpszSQL = NULL, DWORD dwOptions = none );
    throw( CDBException, CMemoryException );Return ValueNonzero if the CRecordset object was successfully opened; otherwise 0 if CDatabase::Open (if called) returns 0.ParametersnOpenTypeAccept the default value, AFX_DB_USE_DEFAULT_TYPE, or use one of the following values from the enum OpenType: CRecordset::dynaset   A recordset with bi-directional scrolling. The membership and ordering of the records are determined when the recordset is opened, but changes made by other users to the data values are visible following a fetch operation. Dynasets are also known as keyset-driven recordsets.
    CRecordset::snapshot   A static recordset with bi-directional scrolling. The membership and ordering of the records are determined when the recordset is opened; the data values are determined when the records are fetched. Changes made by other users are not visible until the recordset is closed and then reopened.
    CRecordset::dynamic   A recordset with bi-directional scrolling. Changes made by other users to the membership, ordering, and data values are visible following a fetch operation. Note that many ODBC drivers do not support this type of recordset.
    CRecordset::forwardOnly   A read-only recordset with only forward scrolling.
    For CRecordset, the default value is CRecordset::snapshot. The default-value mechanism allows the Visual C++ wizards to interact with both ODBC CRecordset and DAO CDaoRecordset, which have different defaults.For more information about these recordset types, see the articleRecordset (ODBC) in Visual C++ Programmer’s Guide. For related information, see the article ”Using Block and Scrollable Cursors" in the ODBC SDK Programmer's Reference.Caution   If the requested type is not supported, the framework throws an exception.lpszSQLA string pointer containing one of the following: A NULL pointer.
    The name of a table.
    An SQL SELECT statement (optionally with an SQL WHERE or ORDER BY clause). 
    A CALL statement specifying the name of a predefined query (stored procedure). Be careful that you do not insert whitespace between the curly brace and the CALL keyword.
    For more information about this string, see the table and the discussion of ClassWizard’s role under Res.Note   The order of the columns in your result set must match the order of the RFX or Bulk RFX function calls in your DoFieldExchange or DoBulkFieldExchange function override.dwOptionsA bitmask which can specify a combination of the values listed below. Some of these are mutually exclusive. The default value is none. CRecordset::none   No options set. This parameter value is mutually exclusive with all other values. By default, the recordset can be updated with Edit or Delete and allows appending new records with AddNew. Updatability depends on the data source as well as on the nOpenType option you specify. Optimization for bulk additions is not available. Bulk row fetching will not be implemented. Deleted records will not be skipped during recordset navigation. Books are not available. Automatic dirty field checking is implemented.
    CRecordset::appendOnly   Do not allow Edit or Delete on the recordset. Allow AddNew only. This option is mutually exclusive with CRecordset::readOnly.
    CRecordset::readOnly   Open the recordset as read-only. This option is mutually exclusive with CRecordset::appendOnly.
    CRecordset::optimizeBulkAdd   Use a prepared SQL statement to optimize adding many records at one time. Applies only if you are not using the ODBC API function SQLSetPos to update the recordset. The first update determines which fields are ed dirty. This option is mutually exclusive with CRecordset::useMultiRowFetch.
    CRecordset::useMultiRowFetch   Implement bulk row fetching to allow multiple rows to be retrieved in a single fetch operation. This is an advanced feature designed to improve performance; however, bulk record field exchange is not supported by ClassWizard. This option is mutually exclusive with CRecordset::optimizeBulkAdd. Note that if you specify CRecordset::useMultiRowFetch, then the option CRecordset::noDirtyFieldCheck will be turned on automatically (double buffering will not be available); on forward-only recordsets, the option CRecordset::useExtendedFetch will be turned on automatically. For more information about bulk row fetching, see the articleRecordset: Fetching Records in Bulk (ODBC) in Visual C++ Programmer’s Guide.
    CRecordset::skipDeletedRecords   Skip all deleted records when navigating through the recordset. This will slow performance in certain relative fetches. This option is not valid on forward-only recordsets. Note that CRecordset::skipDeletedRecords is similar to driver packing, which means that deleted rows are removed from the recordset. However, if your driver packs records, then it will skip only those records that you delete; it will not skip records deleted by other users while the recordset is open. CRecordset::skipDeletedRecords will skip rows deleted by other users.
    CRecordset::useBooks   May use books on the recordset, if supported. Books slow data retrieval but improve performance for data navigation. Not valid on forward-only recordsets. For more information, see the articleRecordset: Books and Absolute Positions (ODBC) in Visual C++ Programmer’s Guide.
    CRecordset::noDirtyFieldCheck   Turn off automatic dirty field checking (double buffering). This will improve performance; however, you must manually  fields as dirty by calling the SetFieldDirty and SetFieldNull member functions.Note that double buffering in class CRecordset is similar to double buffering in class CDaoRecordset. However, in CRecordset, you cannot enable double buffering on individual fields; you either enable it for all fields or disable it for all fields. For more information about double buffering, see the DAO articleDAO Record Field Exchange: Double Buffering Records in Visual C++ Programmer’s Guide. Note that if you specify the option CRecordset::useMultiRowFetch, then CRecordset::noDirtyFieldCheck will be turned on automatically; however, SetFieldDirty and SetFieldNull cannot be used on recordsets that implement bulk row fetching.
    CRecordset::executeDirect   Do not use a prepared SQL statement. For improved performance, specify this option if the Requery member function will never be called.
    CRecordset::useExtendedFetch   Implement SQLExtendedFetch instead of SQLFetch. This is designed for implementing bulk row fetching on forward-only recordsets. If you specify the option CRecordset::useMultiRowFetch on a forward-only recordset, then CRecordset::useExtendedFetch will be turned on automatically.
    CRecordset::userAllocMultiRowBuffers   The user will allocate storage buffers for the data. Use this option in conjunction with CRecordset::useMultiRowFetch if you want to allocate your own storage; otherwise, the framework will automatically allocate the necessary storage. For more information, see the articleRecordset: Fetching Records in Bulk (ODBC) in Visual C++ Programmer’s Guide. Note that specifying CRecordset::userAllocMultiRowBuffers without specifying CRecordset::useMultiRowFetch will result in a failed assertion. 
      

  4.   

    还是有问题,我用
    m_pSet->Open(CRecordset::dynaset ,NULL,CRecordset::none),
    系统提示“odbc驱动程序不支持动态记录集”),是不是向导中设成了snapshot就没法再改变了?
    在向导中我选了文件支持的。
      

  5.   

    可以使用DAO来直接打开数据库文件
      

  6.   

    可以使用DAO来直接打开数据库文件
      

  7.   

    是的,我同意的,ado就是比较方便店
      

  8.   

    这下又奇怪了,
    我用ado返工,
    选了原来那张数据库表,
    结果提示说“unrecognized database format...",
    而我选本机上另一个ado程序附带的一张表却正常,这又是为什么???
      

  9.   

    哎呀,过了很久才看见这张帖子。
    mm1ss2hh3,我和你遇到相同的问题!请问你是如何解决你的最后一个问题的?谢谢,如果你能看见的话!