4、SQL查詢
記錄集的建立實際上是一個查詢過程,SQL的SELECT語句用來查詢資料來源。在建立記錄集時,CRecordset會根據一些引數構造一個SELECT語句來查詢資料來源,並用查詢的結果建立記錄集。SELECT語句的句法如下:
SELECT rfx-field-list FROM table-name [WHERE m_strFilter][ORDER BY m_strSort]
其中table-name是表名,rfx-field-list是選擇的列(欄位),WHERE和ORDER BY是兩個子句,分別用來過濾和排序。舉例如下:
(1)SELECT CourseID, InstructorID FROM Section
從Section表中選擇CourseID和InstructorID欄位。
(2)SELECT * FROM Section WHERE CourseID='MATH202’ AND Capacity=15
從Section表中選擇CourseID為MATH202且Capacity等於15的記錄。該語句中使用了像AND或OR這樣的邏輯連線符。
(3)SELECT InstructorID FROM Section ORDER BY CourseID ASC
從Section表中選擇InstructorID列並且按CourseID的升序排列,若要降序排列,可使用關鍵字DESC。
注意:
(1)在SQL語句中引用字串、日期或時間等型別的資料時要用單引號括起來,而數值型資料則不用。
(2)如果列名或表名中包含有空格,則必須用方括號把該名稱包起來。例如,如果有一列名為“Client Name”,則應該寫成“[Client Name]”。
5、記錄集的建立和關閉
要建立記錄集,首先要構造一個CRecordset派生類物件,然後呼叫Open成員函式查詢資料來源中的記錄並建立記錄集。在Open函式中,可能會呼叫GetDefaultConnect和GetDefaultSQL函式。函式的宣告為:
CRecordset(CDatabase* pDatabase=NULL);
引數pDatabase指向一個CDatabase物件,用來獲取資料來源。如果pDatabase為NULL,則會在Open函式中自動構建一個CDatabase物件。如果CDatabase物件還未與資料來源連線,那麼在Open函式中會建立連線,連線字串由成員函式GetDefaultConnect提供。
virtual CString GetDefaultConnect( );
該函式返回預設的連線字串。Open函式在必要的時侯會呼叫該函式獲取連線字串以建立與資料來源的連線。一般需要在CRecordset派生類中覆蓋該函式並在新版的函式中提供連線字串。
virtual BOOL Open( UINT nOpenType = AFX_DB_USE_DEFAULT_TYPE, LPCTSTR lpszSQL = NULL, DWORD dwOptions = none ); throw( CDBException, CMemoryException );
該函式使用指定的SQL語句查詢資料來源中的記錄並按指定的型別和選項建立記錄集。引數說明如下:
(1)nOpenType
記錄集的型別。如果要求的型別驅動程式不支援,則函式將產生一個異常。
型別 |
含義 |
AFX_DB_USE_DEFAULT_TYPE |
使用預設值。 |
CRecordset::dynaset |
可雙向滾動的動態集。 |
CRecordset::snapshot |
可雙向滾動的快照。 |
CRecordset::dynamic |
提供比動態集更好的動態特性,大部分ODBC驅動程式不支援這種記錄集。 |
CRecordset::forwardOnly |
只能前向滾動的只讀記錄集。 |
(2)lpszSQL
一個SQL的SELECT語句,或是一個表名。函式用lpszSQL來進行查詢,如果該引數為NULL,則函式會呼叫GetDefaultSQL獲取預設的SQL語句。
virtual CString GetDefaultSQL( );
下面舉幾個返回字串的例子:
“Section” //選擇Section表中的所有記錄到記錄集中 “Section, Course” //合併Section表和Course表的各列到記錄集中 //對Section表中的所有記錄按CourseID的升序進行排序,然後建立記錄集 “SELECT * FROM Section ORDER BY CourseID ASC”
(3)dwOptions
一些選項的組合。
選項 |
含義 |
CRecordset::none |
無選項(預設)。 |
CRecordset::appendOnly |
不允許修改和刪除記錄,但可以新增記錄。 |
CRecordset::readOnly |
記錄集是隻讀的。 |
CRecordset::skipDeletedRecords |
有些資料庫(如FoxPro)在刪除記錄時並不真刪除,而是做個刪除標記,在滾動時將跳過這些被刪除的記錄。 |
注意:如果在呼叫Open時只提供了表名,那麼SELECT語句還缺少選擇列引數rfx-field-list。框架規定,如果只提供了表名,則選擇列的資訊從DoFieldExchange中的RFX語句裡提取。例如:如果在呼叫Open時只提供了“Section”表名,那麼將會構造如下一個SELECT語句:
SELECT CourseID,SectionNo,InstructorID,RoomNo,Schedule,Capacity FROM Section
6、m_strFilter與m_strSort
建立記錄集後,使用者可以隨時呼叫Requery成員函式來重新查詢和建立記錄集。Requery有兩個重要用途:
(1)使記錄集能反映使用者對資料來源的改變。
(2)按照新的過濾或排序方法查詢記錄並重新建立記錄集。
在呼叫Requery之前,可呼叫CanRestart來判斷記錄集是否支援Requery操作。要記住Requery只能在成功呼叫Open後呼叫,所以程式應呼叫IsOpen來判斷記錄集是否已建立。
virtual BOOL Requery( ); throw( CDBException,CMemoryException );
BOOL CanRestart( ) const; //若支援Requery則返回TRUE
CRecordset類有兩個公共資料成員m_strFilter和m_strSort用來設定對記錄的過濾和排序。在呼叫Open或Requery前,如果在這兩個資料成員中指定了過濾或排序,那麼Open和Requery將按這兩個資料成員指定的過濾和排序來查詢資料來源。
(1)m_strFilter
用於指定過濾器。m_strFilter實際上包含了SQL的WHERE子句的內容,但它不含WHERE關鍵字。例如:
m_pSet->m_strFilter=“CourseID=‘MATH101’”; //只選擇CourseID為MATH101的記錄
(2)m_strSort
用於指定排序。m_strSort實際上包含了ORDER BY子句的內容,但它不含ORDER BY關鍵字。例如:
m_pSet->m_strSort=“CourseID DESC”; //按CourseID的降序排列記錄
Open函式在構造SELECT語句時,會把m_strFilter和m_strSort的內容放入SELECT語句的WHERE和ORDER BY子句中。如果在Open的lpszSQL引數中已包括了WHERE和ORDER BY子句,那麼m_strFilter和m_strSort必需為空。
呼叫無引數成員函式Close可以關閉記錄集。在呼叫了Close函式後,程式可以再次呼叫Open建立新的記錄集。CRecordset的解構函式會呼叫Close函式,所以當刪除CRecordset物件時記錄集也隨之關閉。