共用方式為


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-name

CRecordset::Open 會呼叫 GetDefaultSQL 以取得資料表名稱。 產生的字串是 2 到 5 的其中一個案例,視 GetDefaultSQL 傳回的項目而定。
2 資料表名稱 SELECT rfx-field-list FROM table-name

欄位清單取自 DoFieldExchange 中的 RFX 陳述式。 如果 m_strFilterm_strSort 不是空的,請將新增 WHERE 和/或 ORDER BY 子句。
3* 完整的 SELECT 陳述式,但沒有 WHEREORDER BY 子句 如所傳遞。 如果 m_strFilterm_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)

另請參閱

SQL:SQL 和 C++ 資料類型 (ODBC)
SQL:製作直接的 SQL 呼叫 (ODBC)