SQL:自訂資料錄集的 SQL 陳述式 (ODBC)
本主題將說明:
架構如何建構 SQL 陳述式
如何覆寫 SQL 陳述式
注意
此資訊適用於 MFC ODBC 類別。 如果您使用的是 MFC DAO 類別,請參閱 DAO 說明中的「Microsoft 資料庫引擎 SQL 與 ANSI SQL 之比較」主題。
SQL 陳述式建構
您的資料錄集主要以 SQL SELECT 陳述式為基礎來選取記錄。 使用精靈宣告類別時,它會撰寫 GetDefaultSQL
成員函式的覆寫版本,看起來像這樣 (針對名為 CAuthors
的資料錄集類別)。
CString CAuthors::GetDefaultSQL()
{
return "AUTHORS";
}
根據預設,此覆寫會傳回您使用精靈指定的資料表名稱。 在範例中,資料表名稱為 "AUTHORS"。當您稍後呼叫資料錄集的 Open
成員函式時,Open
會建構該格式的最終 SELECT 陳述式:
SELECT rfx-field-list FROM table-name [WHERE m_strFilter]
[ORDER BY m_strSort]
其中的 table-name
是透過呼叫 GetDefaultSQL
取得,並從 DoFieldExchange
中的 RFX 函式呼叫取得 rfx-field-list
。 除非您在執行階段以覆寫版本取代 SELECT 陳述式,否則這會是您取得的,不過您也可以使用參數或篩選來修改預設的陳述式。
注意
如果您指定包含 (或可以包含) 空格的資料行名稱,則必須以方括弧括住名稱。 例如,名稱 "First Name" 應該是 "[First Name]"。
若要覆寫預設 SELECT 陳述式,請在呼叫 Open
時傳遞包含完整 SELECT 陳述式的字串。 資料錄集會使用您提供的字串,而不是建構其自己的預設字串。 如果您的取代陳述式包含 WHERE 子句,請勿在 m_strFilter
中指定篩選,因為您那樣會有兩個篩選陳述式。 同樣地,如果您的取代陳述式包含 ORDER BY 子句,請勿在 m_strSort
中指定排序,這樣您就不會有兩個排序陳述式。
注意
如果您在篩選 (或 SQL 陳述式的其他部分) 中使用常值字串,您可能必須使用 DBMS 特定的常值前置詞和常值尾碼字元 (或字元) 括住這類字串。
視 DBMS 而定,針對外部聯結等作業,您可能也會遇到特殊的語法需求。 使用 ODBC 函式從 DBMS 的驅動程式取得此資訊。 例如,呼叫 ::SQLGetTypeInfo
以取得特定資料類型,例如 SQL_VARCHAR
,以要求 LITERAL_PREFIX 和 LITERAL_SUFFIX 字元。 如果您要撰寫與資料庫無關的程式碼,請參閱 ODBC 程式設計人員參考中的附錄 C:SQL 文法,以取得詳細的語法資訊。
除非您傳遞自訂 SQL 陳述式,否則資料錄集物件會建構用來選取記錄的 SQL 陳述式。 完成此作業的方式主要取決於您傳入 Open
成員函式的 lpszSQL 參數的值。
SQL SELECT 陳述式的一般格式為:
SELECT [ALL | DISTINCT] column-list FROM table-list
[WHERE search-condition][ORDER BY column-list [ASC | DESC]]
將 DISTINCT 關鍵字新增至資料錄集的 SQL 陳述式的其中一種方式,是在 DoFieldExchange
中的第一個 RFX 函式呼叫中內嵌關鍵字。 例如:
...
RFX_Text(pFX, "DISTINCT CourseID", m_strCourseID);
...
注意
請只搭配開啟為唯讀的資料錄集使用此技術。
覆寫 SQL 陳述式
下表顯示 lpszSQL 參數為 Open
的可能性。 表格之後說明資料表中的案例。
lpszSQL 參數和產生的 SQL 字串
大小寫 | 您傳入 lpszSQL 的內容 | 產生的 SELECT 陳述式 |
---|---|---|
1 | NULL | SELECT rfx-field-list FROM table-nameCRecordset::Open 會呼叫 GetDefaultSQL 以取得資料表名稱。 產生的字串是 2 到 5 的其中一個案例,視 GetDefaultSQL 傳回的項目而定。 |
2 | 資料表名稱 | SELECT rfx-field-list FROM table-name 欄位清單取自 DoFieldExchange 中的 RFX 陳述式。 如果 m_strFilter 和 m_strSort 不是空的,請將新增 WHERE 和/或 ORDER BY 子句。 |
3* | 完整的 SELECT 陳述式,但沒有 WHERE 或 ORDER BY 子句 | 如所傳遞。 如果 m_strFilter 和 m_strSort 不是空的,請將新增 WHERE 和/或 ORDER BY 子句。 |
4* | 具有 WHERE 和/或 ORDER BY 子句的完整 SELECT 陳述式 | 如所傳遞。 m_strFilter 和/或 m_strSort 必須保持空白,否則會產生兩個篩選和/或排序陳述式。 |
5 * | 預存程序的呼叫 | 如所傳遞。 |
* m_nFields
必須小於或等於 SELECT 陳述式中指定的資料行數目。 SELECT 陳述式中所指定每個資料行的資料類型必須與對應 RFX 輸出資料行的資料類型相同。
案例 1 lpszSQL = NULL
資料錄集選取項目取決於 CRecordset::Open
呼叫它時 GetDefaultSQL
傳回項目。 案例 2 到 5 描述可能的字串。
案例 2 lpszSQL = 資料表名稱
資料錄集會使用記錄欄位交換 (RFX),從資料錄集類別的 DoFieldExchange
覆寫中提供的資料行名稱建置資料行清單。 如果您使用精靈來宣告資料錄集類別,則此案例的結果會與案例 1 相同 (前提是您傳遞精靈中指定相同的資料表名稱)。 如果您不使用精靈來撰寫類別,案例 2 是建構 SQL 陳述式的最簡單方式。
下列範例會建構從 MFC 資料庫應用程式選取記錄的 SQL 陳述式。 當架構呼叫 GetDefaultSQL
成員函式時,函式會傳回資料表 SECTION
的名稱。
CString CEnrollSet::GetDefaultSQL()
{
return "SECTION";
}
若要取得 SQL SELECT 陳述式的資料行名稱,架構會呼叫 DoFieldExchange
成員函式。
void CEnrollSet::DoFieldExchange(CFieldExchange* pFX)
{
pFX->SetFieldType(CFieldExchange::outputColumn);
RFX_Text(pFX, "CourseID", m_strCourseID);
RFX_Text(pFX, "InstructorID", m_strInstructorID);
RFX_Text(pFX, "RoomNo", m_strRoomNo);
RFX_Text(pFX, "Schedule", m_strSchedule);
RFX_Text(pFX, "SectionNo", m_strSectionNo);
}
完成時,SQL 陳述式看起來像這樣:
SELECT CourseID, InstructorID, RoomNo, Schedule, SectionNo
FROM SECTION
案例 3 lpszSQL = SELECT/FROM 陳述式
您可以手動指定資料行清單,而不是依賴 RFX 自動建構它。 您可能會想要在下列情況下執行此動作:
您想要在 SELECT 之後指定 DISTINCT 關鍵字。
您的資料行清單應該符合
DoFieldExchange
中所列相同順序的資料行名稱和類型。您有理由使用 ODBC 函式
::SQLGetData
來手動擷取資料行值,而不是依賴 RFX 為您繫結和擷取資料行。例如,您可能想要容納在散發應用程式之後,新增至資料庫資料表的應用程式客戶新資料行。 您必須新增這些額外的欄位資料成員,在您使用精靈宣告類別時並不知道這些資料成員。
您的資料行清單應該符合
DoFieldExchange
中所列相同順序的資料行名稱和類型,後面接著手動繫結資料行的名稱。 如需詳細資訊,請參閱資料錄集:動態地繫結資料行 (ODBC)。您要藉由在 FROM 子句中指定多個資料表來聯結資料表。
如需資訊和範例,請參閱資料錄集:執行聯結 (ODBC)。
案例 4 lpszSQL = SELECT/FROM 加上 WHERE 和/或 ORDER BY
您可以指定所有項目:資料行清單 (根據 DoFieldExchange
中的 RFX 呼叫)、資料表清單,以及 WHERE 和/或 ORDER BY 子句的內容。 如果您以此方式指定 WHERE 和/或 ORDER BY 子句,請勿使用 m_strFilter
和/或 m_strSort
。
案例 5 lpszSQL = 預存程序呼叫
如果您需要呼叫預先定義的查詢 (例如Microsoft SQL Server 資料庫中的預存程序),您必須在傳遞給 lpszSQL 的字串中撰寫 CALL 陳述式。 精靈不支援宣告資料錄集類別來呼叫預先定義的查詢。 並非所有預先定義的查詢都會傳回記錄。
如果預先定義的查詢未傳回記錄,您可以直接使用 CDatabase
成員函式 ExecuteSQL
。 對於會傳回記錄的預先定義查詢,您也必須針對程序傳回的任何資料行在 DoFieldExchange
中手動寫入 RFX 呼叫。 RFX 呼叫必須與預先定義的查詢為相同順序並傳回相同類型。 如需詳細資訊,請參閱資料錄集:宣告預先定義的查詢類別 (ODBC)。