CRecordset::Open

virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE,
                   LPCTSTR lpszSQL = NULL,
                   DWORD dwOptions = none
                 );
  throw( CDBException, CMemoryException );

返回值:
如果CRecordset对象被成功打开,则返回非零值;否则,如果CDatabase::Open(如果被调用了)返回0,则返回0。

参数:
nOpenType接收缺省值AFX_DB_USE_DEFAULT_TYPE,或使用下列enumOpenType枚举值之一:
·CRecordset::dynaset可以双向滚动的记录集。当记录集被打开时,记录集的全体成员和记录的顺序都被确定,但是伴随一次获取操作,其它用户对数据值所做的改变是可见的。
·CRecordset::snapshot可以双向滚动的静态记录集。当记录集被打开时,记录集的全体成员和记录的顺序都被确定了;当记录被获取时,其数据值是确定的。其它用户在记录集被关闭,然后在打开之前是不可见的。
·CRecordset::dynamic可以双向滚动的记录集。伴随一次获取操作,其它用户对成员,顺序和数据值所做的改变是可见的。注意,许多ODBC驱动器是不支持这种类型的记录集的。
·CRecordset::forwardOnly只能向前滚动的只读的记录集。
对于CRecordset来说,缺省的值是CRecordset::snapshot。这种缺省值机制,允许Visual C++向导与具有不同缺省值的ODBC CRecordset和DAO CDaoRecordset进行交互。
与此有关的信息,参见“ODBC SDK程序员参考”中文章的“使用块和可滚动游标”。
警告:如果不支持要求的类型,框架将抛出一个异常。
lpszSQL一个包含下列值之一的字符串指针:
·一个NULL指针。
·一个表名。
·一条SQL SELECT语句(可选择带一条SQL WHERE 或ORDER BY子句)。
·一条CALL语句,指定一个预定义查询(存储过程)名。注意,你不能在卷括号和CALL关键字之间插入空格。
有关这个字符串的更多信息,请参见说明下的表,以及对ClassWizard的作用的讨论。
注意:
在你的结果集中,列的顺序必须与在你的重载的DoFieldExchange或DoBulkFieldExchange函数中的RFX和Bulk RFX函数调用的顺序相匹配。
dwOptions一个bitmask,它可以指定下列值的组合。这些值中的某些是相互独立的。缺省的值是none。
·CRecordset::none未设置选项。此参数值与所有其它的值是相互独立的。缺省的,记录集可以用Edit或Delete来更新,并允许用AddNew来添加新记录。这种可更新性依赖于数据源,就像你所指定的nOpenType选项。成组添加的优化是没有用的。成组行检取不会被实现。在记录集中导航时,不能略过被删除的记录。书签是没有用的。实现了自动脏字段检查。
·CRecordset::appendOnly不允许在记录集中进行Edit或Delete。值允许AddNew。此选项与CRecordset::readOnly相互独立。
·CRecordset::readOnly用只读方式打开记录集。此选项与CRecordset::appendOnly相互独立。
·CRecordset::optimizeBulkAdd使用预备的SQL语句来优化一次添加多个记录。只有在你不使用ODBC API函数SQLSetPos来更新记录集时才使用。第一次更新确定将哪一个字段标记为脏的。此选项与CRecordset::useMultiRowFetch相互独立。
·CRecordset::useMultiRowFetch实现成组行检取,允许在一次检取操作中获取多行。这是一个高级特征,是设计来提高性能的;但是,ClassWizard不支持成组记录字段交互。此选项与CRecordset::optimiazBulkAdd相互独立。注意,如果你指定了CRecordset::useMultiRowFetch,则选项CRecordset::noDirtyFieldCheck将自动被返回(双缓冲将无效);对于只向前记录集,选项CRecordset::useExtendedFetch将被自动返回。
·CRecordset::skipDeletedRecords当在记录集中导航时,略过所有已被删除的记录。这将使某个相关获取的性能下降。在一个只向前的记录集中,此选项是无效的。注意,CRecordset::skipDeletedRecords与“驱动器包装”相似,驱动器包装意味着被删除的行被从记录集中移走。但是,如果你的驱动器包装记录,则它将只略过那些被你删除的记录;而不会略过在记录集打开时被其它用户删除的记录。CRecordset::skipDeletedRecords将会略过被其它用户删除的记录。
·CRecordset::useBookarks允许在记录集中使用书签,如果支持书签的话。书签会使数据检取变慢,但是会提高数据导航的性能。在只向前的记录集中此选项是无效的。
·CRecordset::noDirtyFieldCheck关闭自动脏数据检查(双缓冲)。这将提高性能;但是,你必须通过调用SetFieldDirty和SetFieldNull成员函数来手动标记变脏的字段。注意,CRecordset类中的双缓冲类似于CDaoRecordset中的双缓冲。但是,在CRecordset中,你不能在独立字段中使双缓冲有效;你只能对所有字段使它有效或无效。注意,如果你指定了选项CRecordset::useMultiRowFetch,则CRecordset::noDirtyFieldCheck将被自动返回;但是,SetFieldDirty和SetFieldNull不能在实现成组行检取的记录集中使用。
·CRecordset::executeDirect不要使用预备的SQL语句。如果永远不会调用Requery成员函数,则指定此选项来提高性能。
·CRecordset::useExtendedFetch实现SQLException来代替SQLFetch。这是设计来在只向前的记录集中实现成组行检取的。如果你在一个只向前的记录集中指定了选项CRecordset::userMultiRowFetch,则CRecordset::useExtendedFetch将被自动返回。
·CRecordset::userAllocMultiRowBuffers用户将为数据分配存储缓存。如果你想分配自己的存储区,将此选项用与CRecordset::useMultiRowFetch连接;否则,框架将自动分配必要的存储区。注意,指定了CRecordset::userAllocMutiRowBuffers,而没有指定CRecordset::useMultiRowFetch,将导致一个失败断言。

说明:
你必须调用此成员函数来运行记录集定义的查询。在调用Open之前,你必须构造记录集对象。
此记录集与数据源的连接依赖于在调用Open之前你是如何构造这个记录集的。如果你将一个没有连接到一个数据源的CDatabase对象传递给记录集构造函数,此成员函数使用GetDefaultConnect来尝试打开该数据库对象。如果你将NULL传递给记录集构造函数,则此成员函数为你构造一个CDatabase对象,并且Open试图连接给数据库对象。有关关闭记录集和在这些不同的环境下的连接的细节,请参见Close。
注意:
通过一个CRecordset对象对数据源的访问总是被共享的。不像CDaoRecordset类,不能使用一个CRecordset对象来打开一个具有独占访问的数据源。
当你调用Open时,一条查询语句,通常是一条SQL SELECT语句,基于下表给出的标准来选择记录:
lpszSQL参数的值选择的记录所决定于示例
NULL由GetDefaultSQL返回的字符串 
SQL表名在DoFieldExchange或DoBulkFieldExchange中的列表的所有列"Customer"
预定义的查询(存储过程)名称该查询被定义的要返回的列"{callOverDueAccts}"
SELECT 列表  FROM 列表从指定的表中选出的指定的列"SELECT CustId, CustName FROM Customer"
警告:
注意,在SQL字符串中,你不能插入额外的空格。例如,如果你在卷括号和CALL关键字之间插入了空格,MFC将错误地将这个SQL串解释为一个表名,并将它合并到SELECT语句中,这将导致抛出一个异常。
类似地,如果使用输出参数的预定义查询没有在卷括号和‘?’号之间插入空格,则也会导致抛出异常。最后,你不能在一个CALL语句中的卷括号之前和在一个SELECT语句中的SELECT关键字之前插入空格。
通常的程序是将NULL传递给Open;在这种情况下,Open调用GetDefaultSQL。如果你正在使用一个CRecordset派生类,GetDefaultSQL给出你在ClassWizard中指定的表名。你可以代替在lpszSQL参数中指定其它的信息。
不管传递的是什么,Open都为查询构造一个最后的SQL字符串(该字符串可能有SQL WHERE和ORDER BY子串添加在你传递的lpszSQL串中),然后执行这个查询。你可以在调用Open之后通过调用GetSQL来检查这个构造出来的字符串。
记录集类的字段数据成员与所选择数据的列相关联。如果有记录被返回,则第一个记录成为当前记录。
如果你想为记录集设置选项,比如一个过滤器或排序,则应在构造了此记录集对象之后,但在调用Open之前指定这些选项。如果你要在记录集被打开之后刷新记录集中的记录,可以调用Requery。

示例:
下面的代码例子说明了Open调用的不同形式。
// rs 是一个CRecordset或CRecordset派生对象
// 用缺省的SQL语句打开rs
// 实现书签,并关闭自动脏数据检查
rs.Open( CRecordset::snapshot, NULL, CRecordset::useBookmarks | CRecordset::noDirtyFieldCheck );
// 传递一个完整的SELECT语句并打开作为一个动态集
rs.Open( CRecordset::dynaset, _T( "Select L_Name from Customer" ) );
// 接收所有的缺省值
rs.Open( );

请参阅:
CRecordset::CRecordset, CRecordset::Close, CRecordset::GetDefaultSQL, CRecordset::GetSQL, CRecordset::m_strFilter, CRecordset::m_strSort, CRecordset::Requery