那麼問題是,ODBC 如何標準化資料庫存取? 有兩項建築要求:
應用程式必須能夠使用相同的原始碼存取多個資料庫管理系統,而無需重新編譯或重新連結。
應用程式必須能同時存取多個資料庫管理系統(DBMS)。
還有一個問題,根據市場現實:
- ODBC 應該公開哪些資料庫管理系統功能? 只有所有資料庫管理系統共有的功能,還是任何資料庫管理系統中可用的功能?
ODBC 以以下方式解決這些問題:
ODBC 是一種呼叫層級介面。 為了解決應用程式如何使用相同原始碼存取多個資料庫管理系統的問題,ODBC 定義了一個標準的 CLI。 此系統包含 Open Group 與 ISO/IEC 的 CLI 規範中的所有功能,並提供應用程式常見的額外功能。
每個支援 ODBC 的資料庫系統都需要不同的函式庫或驅動程式。 驅動程式實作了 ODBC API 中的函式。 若要使用不同的驅動程式,應用程式不需要重新編譯或重新連結。 應用程式會直接載入新驅動程式並呼叫其中的函式。 要同時存取多個資料庫管理系統,應用程式會載入多個驅動程式。 驅動程式的支援方式依作業系統而異。 例如,在 Microsoft Windows 作業系統中,驅動程式是動態連結函式庫(DLL)。
ODBC 定義了標準的 SQL 文法。 除了標準的呼叫層介面外,ODBC 還定義了標準的 SQL 文法。 此文法基於 Open Group SQL CAE 規範。 這兩種文法之間的差異很小,主要是因為嵌入式 SQL(開放小組)和 CLI(ODBC)所需的 SQL 文法差異。 文法也有一些擴充,以揭露開放群體文法未涵蓋的常見語言特徵。
申請可使用 ODBC 或 DBMS 專屬語法提交陳述。 如果某個語句使用 ODBC 文法且與 DBMS 專屬文法不同,驅動程式會在傳送到資料來源前將其轉換。 然而,這類轉換較為罕見,因為大多數資料庫管理系統已使用標準 SQL 文法。
ODBC 提供驅動程式管理器,以管理多個資料庫管理系統的同時存取。 雖然驅動程式的使用解決了同時存取多個資料庫管理系統(DBMS)的問題,但執行此事的程式碼可能相當複雜。 設計為支援所有驅動程式的應用程式,無法靜態連結到任何驅動程式。 相反地,它們必須在執行時載入驅動程式,並透過函式指標表呼叫其中的函式。 若應用程式同時使用多個驅動程式,情況會更複雜。
ODBC 不強制每個應用程式都這麼做,而是提供驅動程式管理器。 驅動程式管理器實作了所有 ODBC 函式——多半是作為驅動程式中 ODBC 函式的直通呼叫——並靜態連結至應用程式,或由應用程式在執行時載入。 因此,應用程式會在驅動程式管理器中以名稱呼叫 ODBC 函式,而非在每個驅動程式中以指標呼叫。
當應用程式需要特定驅動程式時,會先請求一個連接句柄以識別該驅動程式,然後請求驅動程式管理器載入該驅動程式。 驅動程式管理器會載入驅動程式,並將每個函式的位址儲存在驅動程式中。 要呼叫驅動程式中的 ODBC 函式,應用程式會在驅動程式管理器中呼叫該函式,並將該驅動程式的連接句柄傳遞給該程式。 驅動程式管理器接著會使用先前儲存的位址呼叫該函式。
ODBC 公開了大量資料庫管理系統(DBMS)功能,但不要求驅動程式必須支援所有功能。 如果 ODBC 只暴露所有資料庫管理系統共有的功能,那它就幾乎沒什麼用了;畢竟,現今存在這麼多不同的資料庫管理系統,是因為它們擁有不同的功能。 如果 ODBC 公開任何資料庫管理系統中所有可用的功能,驅動程式將無法實作。
相反地,ODBC 暴露了相當多的功能——比大多數資料庫管理系統支援的還多——但驅動程式只實作其中一部分功能。 驅動程式僅在底層資料庫管理系統支援或選擇模擬時,才實作剩餘功能。 因此,應用程式可以被撰寫來利用該 DBMS 驅動程式所暴露的單一資料庫管理系統功能,或僅使用所有 DBMS 使用的功能,或檢查對特定功能的支援並做出相應反應。
為了讓應用程式能判斷驅動程式與資料庫管理系統支援哪些功能,ODBC 提供兩個函式(SQLGetInfo 與 SQLGetFunctions),分別回傳驅動程式與資料庫管理系統功能的一般資訊,以及驅動程式支援的功能清單。 ODBC 也定義了 API 與 SQL 文法的符合性等級,這些等級規範驅動程式所支援的廣泛功能範圍。 欲了解更多資訊,請參閱 合規等級。
重要的是要記住,ODBC 為所有它所暴露的功能定義了一個共同介面。 因此,應用程式包含功能專屬的程式碼,而非資料庫管理系統(DBMS)專屬的程式碼,且可使用任何暴露這些功能的驅動程式。 此舉的一大優點是,當資料庫管理系統(DBMS)支援的功能被增強時,應用程式就不需要更新;相反地,當安裝更新驅動程式時,應用程式會自動使用這些功能,因為其程式碼是針對特定功能,而非驅動程式或資料庫管理系統專屬。