ZLW-NOTE:ODBC Fundamentals - Data Types in ODBC

ODBC使用两组数据类型集:SQL数据类型和C数据类型。SQL数据类型在数据源中使用,C数据类型在C编码的应用程序中使用。
本部分内容包含下面话题:

类型标识符

为了描述SQL数据类型和C数据类型,ODBC定义了两组类型标识符。一个类型标识符描述一个SQL列的类型或者一个C缓冲区的类型。类型标识符是#define的值,通常作为函数的参数或者作为返回的元数据进行传递。
例如,下面程序调用SQLBindParameter将一个SQL_DATE_STRUCT类型的变量绑定到一个SQL语句的date类型参数上。C类型标识符SQL_C_TYPE_DATE指定了变量Date的类型,同时SQL类型标识符SQL_TYPE_DATE指定了动态参数的类型。

SQL_DATE_STRUCT Date;
SQLINTEGER DateInd = 0;
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TYPE_DATE, 0, 0,
&Date, 0, &DateInd);

ODBC中的SQL数据类型

SQL数据类型是数据存储在数据源中使用的类型。
该部分包含两个内容:

SQL类型标识符

每个数据源都会定义自己的SQL数据类型。ODBC定义类型标识符,并且描述与每个类型标识符相关联的SQL数据类型的通用特性。底层数据源中的每种数据类型如何映射到 ODBC 的 SQL 类型标识符是因驱动程序而异的。
例如,SQL_CHAR是一个固定长度(1-254个字符)字符类型列的类型标识符。这些特征同样可以对应于在许多 SQL 数据源中发现的 CHAR 数据类型。因此,当应用程序发现某个列的类型标识符是SQL_CHAR,它就可以认为很可能是在处理一个CHAR类型的列。但是它还是应该在假设这是1到254字符长度前检查列的字节长度;举例,一个非SQL数据源的驱动可能会将一个固定长度500字符的字符类型列映射到SQL_CHAR或SQL_LONGVARCHAR上,因为两者之间不是一个严格的匹配关系。
ODBC定义了大量的SQL类型标识符。但是并不要求驱动必须使用所有的这些标识符。驱动仅使用其对外提供底层数据源支持的SQL数据类型所需的那些标志符就可以了。如果底层数据源支持的SQL数据类型在ODBC标识符中找不到对应的,驱动器可以定义额外的类型标识符。更多信息参照Driver-Specific Data Types,Descriptor Types,Information Types,Diagnostic Types,and Attributes
完整的SQL类型标识符参考附录D:Data Types部分的C Data Types。

使用SQLGetTypeInfo获取数据类型信息

由于底层的SQL数据类型和ODBC类型标识符之间的映射关系复杂,ODBC提供了一个函数SQLGetTypeInfo,通过该函数可以驱动器可以完整地描述数据源中地每个SQL数据类型。该函数返回一个结果集,其中的每一行单独描述一种数据类型的特性,包括名称、类型、精度、规模、是否可为空等。
通常地,这些信息在允许用户创建和修改表的通用程序中会被用到。这类程序调用SQLGetTypeInfo获取数据类型信息然后向用户展示其中一些或所有信息。这类应用需要明确下面两项内容:

  • 多个SQL数据类型可以映射到一个类型标识符上,这会导致选择使用哪种数据类型变得困难。为了解决这个问题,结果集首先按照类型标识符排序,然后按照跟类型标识符定义的接近程度排序。除此之外,数据源定义的数据类型优先于用户定义的数据类型。例如,假设一个数据源定义INTERGER类型和COUNTER类型,除了COUNTER类型是自增的以外,两种类型其他都一样。通用假设一个用户定义的类型WHOLENUM是INTEGER类型的别名。这三个类型都映射到SQL_INTEGER。在SQLGetTypeInfo结果集中,INTEGER第一个出现,接下来是WHOLENUM然后是COUNTER。WHOLENUM在INTEGER之后是一i那我它是用户定义的,出现在COUNTER之前是因为它比COUNTER更接近SQL_INTEGER类型标识符的定义。
  • ODBC 没有定义用于 CREATE TABLE 和 ALTER TABLE 语句的数据类型名称。 相反,应用程序应该使用SQLGetTypeInfo返回结果集的TYPE_NAME列中的名称。 这样做的原因是,尽管大多数 SQL 在 DBMS 之间没有太大差异,但数据类型名称差异很大。 与其强制驱动器解析SQL语句并将标准数据类型名称替换为DBMS特定的数据类型名称,ODBC选择让应用程序首选使用DBMS特定的名称。
    需要注意的是SQLGetTypeInfo并不需要描述所有应用程序会遇到的数据类型。特别地,结果集可能包含一些数据源不直接支持的数据类型。例如,catalog函数返回的结果集的列类型是ODBC定义的,这些类型可能在数据源中不支持。应用程序调用SQLColAttribute来确定结果集中的数据类型的特性。

ODBC中的C数据类型

在ODBC3.8中,用户可以指定特定于驱动程序的C数据类型。这样可以允许用户在应用程序中调用SQLBindCol, SQLGetData, SQLBindParameter时将一个SQL类型绑定为一个特定于驱动程序的C类型。这对支持新的服务器类型来说是很有用的,因为既有的C数据类型可能不能正确地代表新的服务器数据类型。使用特定于驱动程序的C类型可以增加驱动器可以处理的转换的数目。
例如,假设一个数据库管理系统(DBMS)引入了一个新的SQL类型DATETIMEOFFSET,用以表示带时区信息的日期和时间。在ODBC中没有与DATETIMEOFFSET类型相对应的特定C类型。应用程序必须将DATETIMEOFFSET类型绑定为SQL_C_BINARY,并将其转换为用户自定义的数据类型。从C数据类型可扩展的ODBC3.8开始,驱动程序可以定义新的相应C类型。例如,对新的SQL类型DATETIMEOFFSET,驱动器可以定义一个对应的C类型,比如SQL_C_DATETIMEOFFSET。这样,应用程序就可以将新的SQL类型绑定为特定于驱动程序的C类型。
一个C数据类型在驱动程序中定义如下:

  • 应用程序、ODBC驱动器、驱动器管理器的ODBC兼容版本是3.8(或更高)
  • 特定于驱动器的C类型数据范围在0x4000和0x7FFF之间
  • 驱动器定义C类型对应的数据结构。这可以在驱动程序特定的 SDK 中完成。
    SDK: 软件开发工具包。一般都是一些软件工程师为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件时的开发工具的集合。软件开发工具广义上指辅助开发某一类软件的相关文档、范例和工具的集合。
    对于定义在0x4000到0x7FFF之间的C类型,驱动器管理器不会对其进行检查,驱动器会进行检查以及数据类型转换。但是如果C类型的数值范围在0x0000到0x3FFF之间或者在0x8000到0xFFFF之间,去带动起管理器会检查C数据类型。

    注意:
    特定于驱动器的C数据类型应该在驱动器文档中进行描述。

应用需要调用SQLSetEnvAttr,将SQL_ATTR_ODBC_VERSION属性设置为SQL_OV_ODBC3_80来指定兼容的ODBC版本。应用需要调用SQLGetInfo并指定属性SQL_DRIVER_ODBC_VER来确定驱动器的版本。
更多ODBC3.8的信息参考What's New in ODBC 3.8

也可以看看
C Data Types

数据类型转换

数据从一种类型转换为另一种类型存在以下四种情形:
当数据被从一个应用变量传递到另一个应用变量时(C->C);
当数据从一个应用变量发送给一个语句参数时(C->SQL);
当结果集列中的数据返回到一个应用变量时(SQL->C);
当数据从一个数据源列传递给另一个数据源的列时(SQL->SQL).

数据从一个应用变量传递给另一个应用变量的转换不在本文档的讨论范围之内。
当一个应用程序将一个变量绑定到一个结果集列或一个语句参数上时,应用在选择应用变量的数据类型时隐式地指定了数据类型转换。例如,假设一个列包含整形数据,如果应用程序将一个整形变量绑定到该列,它的选择不涉及类型转换;如果应用程序将一个字符类型变量绑定到高列,它的选择隐式地指定了数据将会从整形转换为字符类型。
ODBC 定义了如何在每种 SQL 和 C 数据类型之间进行数据转换。 基本上来说,ODBC 支持所有合理的转换,例如字符到整数和整数到浮点数,不支持定义不明确的转换,例如浮点数到日期。 驱动程序需要实现其所支持的每种 SQL 数据类型的所有转换。 有关 SQL 和 C 数据类型之间转换的完整列表,请参阅附录 D:Data Types中的Converting Data from SQL to C Data TypesConverting Data from C to SQL Data Types

ODBC 还定义了一个标量函数,用于将数据从一种 SQL 数据类型转换为另一种。 CONVERT 标量函数由驱动程序映射到底层标量函数或定义为在数据源中执行转换的函数。 由于该函数映射到特定于 DBMS 的函数,所以 ODBC 没有定义这些转换如何进行或必须支持哪些转换。 应用程序需通过 SQLGetInfo 中的 SQL_CONVERT 选项来得知特定驱动程序和数据源支持哪些转换。 有关 CONVERT 标量函数的详细信息,请参阅Escape Sequences in ODBC和Explicit Data Type Conversion Function。

posted @ 2022-05-12 23:39  Winnie^^  阅读(56)  评论(0)    收藏  举报