ODBC 解决方案
那么问题在于,ODBC 如何标准化数据库访问? 有两个体系结构要求:
应用程序必须能够使用相同的源代码访问多个 DBMS,而无需重新编译或重新链接。
应用程序必须能够同时访问多个 DBMS。
还有一个问题,由于市场现实:
- ODBC 应公开哪些 DBMS 功能? 仅公开所有 DBMS 共有的功能还是任何 DBMS 中可用的任何功能?
ODBC 通过以下方式解决这些问题:
ODBC 是调用级别接口。 为了解决应用程序如何使用相同的源代码访问多个 DBMS 的问题,ODBC 定义了一个标准 CLI。 这包含 Open Group 和 ISO/IEC 的 CLI 规范中的所有函数,并提供应用程序通常需要的其他函数。
每个支持 ODBC 的 DBMS 都需要不同的库或驱动程序。 驱动程序在 ODBC API 中实现函数。 要使用不同的驱动程序,无需重新编译或重新链接应用程序。 相反,应用程序只需加载新驱动程序并调用其中函数即可。 要同时访问多个 DBMS,应用程序将加载多个驱动程序。 驱动程序的支持方式与操作系统有关。 例如,在 Microsoft Windows 操作系统上,驱动程序是动态链接库 (DLL)。
ODBC 定义标准 SQL 语法。 除了标准调用级别接口外,ODBC 还定义了标准 SQL 语法。 此语法基于 Open Group SQL CAE 规范。 这两种语法之间的差异很小,主要在于嵌入式 SQL (Open Group) 和 CLI (ODBC) 所需的 SQL 语法之间的差异。 语法还有一些扩展,以公开 Open Group 语法未涵盖的常用语言功能。
应用程序可以使用 ODBC 或 DBMS 特定语法提交语句。 如果语句使用不同于 DBMS 特定语法的 ODBC 语法,驱动程序会将其转换为数据源,然后再将其发送到数据源。 但是,此类转换很少见,因为大多数 DBMS 已使用标准 SQL 语法。
ODBC 提供驱动程序管理器来管理对多个 DBMS 的同时访问。 尽管驱动程序的使用解决了同时访问多个 DBMS 的问题,但是执行此操作的代码可能会比较复杂。 专用于处理所有驱动程序的应用程序不能静态链接到任何驱动程序。 相反,其必须在运行时加载驱动程序,并通过函数指针表调用这些驱动程序中的函数。 如果应用程序同时使用多个驱动程序,则情况会变得更加复杂。
ODBC 会提供驱动程序管理器,而不是强制每个应用程序执行此操作。 驱动程序管理器实现所有 ODBC 函数(主要是驱动程序中对 ODBC 函数的传递调用),并以静态方式链接到应用程序或在运行时由应用程序加载。 因此,应用程序在驱动程序管理器中按名称调用 ODBC 函数,而不是通过每个驱动程序中的指针调用。
应用程序需要特定驱动程序时,其首先会请求一个连接句柄,以便标识驱动程序,然后请求驱动程序管理器加载驱动程序。 驱动程序管理器加载驱动程序并将每个函数的地址存储在驱动程序中。 要在驱动程序中调用 ODBC 函数,应用程序会在驱动程序管理器中调用此函数,并传递驱动程序的连接句柄。 然后,驱动程序管理器使用之前存储的地址调用函数。
ODBC 公开大量的 DBMS 功能,但不要求驱动程序支持所有这些功能。 如果 ODBC 只公开了所有 DBMS 通用的功能,则会很少使用这些 DBMS;毕竟,目前存在许多不同的 DBMS 的原因是其拥有不同的功能。 如果 ODBC 公开了任何 DBMS 中可用的每个功能,则驱动程序无法实现这些功能。
相反,ODBC 会公开大量功能(而不是大多数 DBMS 支持的功能),但需要驱动程序仅实现这些功能的子集。 仅当基础 DBMS 支持这些功能或选择模拟 DBMS 时,驱动程序才实现其余功能。 因此,可以编写应用程序来利用此 DBMS 驱动程序公开的单个 DBMS 功能,从而仅使用所有 DBMS 使用的这些功能,或检查对特定功能的支持并做出相应的反应。
因此,应用程序可以确定驱动程序和 DBMS 支持的功能,ODBC 提供了两个函数(SQLGetInfo 和 SQLGetFunctions),这些函数返回有关驱动程序和 DBMS 功能的常规信息,以及驱动程序支持的函数列表。 ODBC 还定义了 API 和 SQL 语法一致性级别,这些级别指定驱动程序支持的各种功能。 有关详细信息,请参阅一致性级别。
切记,ODBC 为公开的所有功能定义通用接口。 因此,应用程序包含特定于功能的代码,而不是特定于 DBMS 的代码,并且可以使用公开这些功能的任何驱动程序。 其中一个优点是在增强 DBMS 支持的功能时,不需要更新应用程序;相反,安装更新的驱动程序时,应用程序会自动使用这些功能,因为其代码特定于功能,而不是特定于驱动程序或 DBMS。