共用方式為


SQL:自訂資料錄集的 SQL 陳述式 (ODBC)

這個主題說明:

  • 此架構要如何建構 SQL 陳述式

  • 如何覆寫 SQL 陳述式

注意事項注意事項

本資訊適用於 MFC ODBC 類別。 如果您正在使用 MFC DAO 類別,請參閱《DAO 說明》中的<比較 Microsoft Jet Database Engine 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 所取得的,而 rfx-field-list 是從 DoFieldExchange 內的 RFX 函式呼叫所取得的。 除非您在執行階段以覆寫版本進行取代,否則這會是您得到的 SELECT 陳述式,但是您仍可用參數或篩選條件來修改預設的陳述式。

注意事項注意事項

如果您指定包含 (或能包含) 空格的資料行名稱,就必須將該名稱放置在方括弧內。 例如,名稱 "First Name" 應該是 "[First Name]"。

若要覆寫預設的 SELECT 陳述式,請在呼叫 Open 時傳遞一個包含完整 SELECT 陳述式的字串。 資料錄集會使用您所提供的字串,而不自行建構其預設字串。 替代陳述式若包含 WHERE 子句,便請不要在 m_strFilter 內指定篩選條件,以防同時出現兩個篩選條件陳述式。 同樣的,如果您的替代陳述式包含 ORDER BY 子句,請不要指定 m_strSort 內的排序,以免擁有兩個排序陳述式。

注意事項注意事項

如果您在篩選條件中使用常值字串 (或 SQL 陳述式的其他部分),您可能必須使用 DBMS 特定的常值前置字元和常值後置字元來「括住」這樣的字串 (放在特定的分隔符號內)。

視 DBMS 而定,您可能也會遭遇到作業上的特殊語法需求,例如外部聯結 (Outer Join)。 使用 ODBC 函式自您的驅動程式取得 DBMS 的資訊。 例如,對如 SQL_VARCHAR 的特別資料型別呼叫 ::SQLGetTypeInfo,以便要求 LITERAL_PREFIXLITERAL_SUFFIX 字元。 如果您正在寫入與資料庫無關的程式碼,請參閱 MSDN Library 光碟片上《ODBC SDK 程式設計人員參考》內的附錄 C 的詳細語法資訊。

除非您傳遞自訂的 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 陳述式

下表內容說明 Open 的 lpszSQL 參數的可能性。 表格內的案例將說明於表格之後。

lpszSQL 參數和產生的 SQL 字串

案例

您在 lpszSQL 中傳遞什麼

產生的 SELECT 陳述式

1

NULL

SELECT rfx-field-list FROM table-name

CRecordset::Open 呼叫 GetDefaultSQL 以取得資料表名稱。 根據 GetDefaultSQL 傳回的內容而定,產生的字串會是案例 2 到 5 的其中一種。

2

任一資料表名稱

SELECT rfx-field-list FROM table-name

欄位清單是取自 DoFieldExchange 內的 RFX 陳述式。 若 m_strFilterm_strSort 不是空的,便會加入 WHERE 和 (或) ORDER BY 子句。

3 *

不含 WHEREORDER BY 子句的完整 SELECT 陳述式

如所傳遞的。 若 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 覆寫中的 RFX 函式呼叫中所提供的資料行名稱,來建立資料行清單。 若您已使用精靈宣告資料錄集類別,這個案例的結果會和案例 1 的結果相同 (條件是您需傳遞在精靈內指定的相同資料表名稱)。 如果您未使用精靈來寫入類別,則案例 2 會是建構 SQL 陳述式最簡單的方式。

下列範例所建構的 SQL 陳述式,會從 MFC 資料庫應用程式選取資料錄。 在架構呼叫 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_strFilterm_strSort

案例 5:lpszSQL = 預存程序呼叫

若您需要呼叫預先定義查詢 (例如 Microsoft SQL Server 資料庫內的預存程序),就必須在傳遞至 lpszSQL 的字串中寫入 CALL 陳述式。 精靈並不支援為呼叫預先定義查詢的資料錄集類別宣告。 並非所有的預先定義查詢都會傳回資料錄。

如果預先定義查詢沒有傳回資料錄,您可直接使用 CDatabase 成員函式 ExecuteSQL。 針對會傳回資料錄的預先定義查詢,您也必須為此程序所傳回的資料行,手動寫入 DoFieldExchange 內的 RFX 呼叫。 RFX 和預先定義查詢一樣,必須有相同的順序,並傳回相同的型別。 如需詳細資訊,請參閱資料錄集:宣告預先定義查詢的類別 (ODBC)

請參閱

概念

SQL:SQL 和 C++ 資料型別 (ODBC)

SQL:製作直接的 SQL 呼叫 (ODBC)