在使用ODBC开发时一个重要的问题就是数据转换的问题,在ODBC中存在下面的几类数据:

l          数据库中SQL语言表达数据的类型

l          ODBC中表达数据的类型

l          C语言中表达数据的类型

在程序运行过程中数据需要经历两次转换:C语言的数据或结构类型与ODBC的数据类型的转换,ODBC与SQL间数据类型的转换。所以ODBC所定义的数据类型起到了中间桥梁的作用,在ODBC的驱动程序调用自己的DBMS数据库访问接口时就需要对数据类型进行转换。我们所需要关注的是C语言的数据类型和ODBC数据类型间的转换关系。

从下图中可以看到ODBC中定义的数据类型和SQL语言中数据类型的对应关系,所以通过下表我们可以将ODBC和SQL语言间的数据一一对应,在后面的文字中我们不再区分ODBC数据类型和SQL语言数据类型。

ODBC数据类型名称

SQL语言数据类型名称

SQL_CHAR

CHAR(n)

SQL_VARCHAR

VARCHAR(n)

SQL_LONGVARCHAR

LONG VARCHAR

SQL_WCHAR

WCHAR(n)

SQL_WVARCHAR

VARWCHAR(n)

SQL_WLONGVARCHAR

LONGWVARCHAR

SQL_DECIMAL

DECIMAL(p,s)

SQL_NUMERIC

NUMERIC(p,s)

SQL_SMALLINT

SMALLINT

SQL_INTEGER

INTEGER

SQL_REAL

REAL

SQL_FLOAT

FLOAT(p)

SQL_DOUBLE

DOUBLE PRECISION

SQL_BIT

BIT

SQL_TINYINT

TINYINT

SQL_BIGINT

BIGINT

SQL_BINARY

BINARY(n)

SQL_VARBINARY

VARBINARY(n)

SQL_LONGVARBINARY

LONG VARBINARY

SQL_TYPE_DATE[6]

DATE

SQL_TYPE_TIME[6]

TIME(p)

SQL_TYPE_TIMESTAMP[6]

TIMESTAMP(p)

SQL_GUID

GUID

图2.5

使用C/C++语言开发,那么必定会在与ODBC语言间存在数据的转换的问题,因为ODBC所存在的一些数据类型在C语言中是不存在的。在ODBC以宏定义的方式定义了C语言和ODBC中使用的数据类型:

C语言数据类型名称

ODBC 数据类型定义

C语言实际类型

SQL_C_CHAR

SQLCHAR *

unsigned char *

SQL_C_SSHORT[j]

SQLSMALLINT

short int

SQL_C_USHORT[j]

SQLUSMALLINT

unsigned short int

SQL_C_SLONG[j]

SQLINTEGER

long int

SQL_C_ULONG[j]

SQLUINTEGER

unsigned long int

SQL_C_FLOAT

SQLREAL

float

SQL_C_DOUBLE

SQLDOUBLE, SQLFLOAT

double

SQL_C_BIT

SQLCHAR

unsigned char

SQL_C_STINYINT[j]

SQLSCHAR

signed char

SQL_C_UTINYINT[j]

SQLCHAR

unsigned char

SQL_C_SBIGINT

SQLBIGINT

_int64[h]

SQL_C_UBIGINT

SQLUBIGINT

unsigned _int64[h]

SQL_C_BINARY

SQLCHAR *

unsigned char *

SQL_C_BOOKMARK[i]

BOOKMARK

unsigned long int[d]

SQL_C_VARBOOKMARK

SQLCHAR *

unsigned char *

SQL_C_TYPE_DATE[c]

SQL_DATE_STRUCT

struct tagDATE_STRUCT {
     SQLSMALLINT year;
     SQLUSMALLINT month;
     SQLUSMALLINT day;
} DATE_STRUCT;[a]

SQL_C_TYPE_TIME[c]

SQL_TIME_STRUCT

struct tagTIME_STRUCT {
     SQLUSMALLINT hour;
     SQLUSMALLINT minute;
     SQLUSMALLINT second;
} TIME_STRUCT;[a]

SQL_C_TYPE_TIMESTAMP[c]

SQL_TIMESTAMP_STRUCT

struct tagTIMESTAMP_STRUCT {
     SQLSMALLINT year;
     SQLUSMALLINT month;
     SQLUSMALLINT day;
     SQLUSMALLINT hour;
     SQLUSMALLINT minute;
     SQLUSMALLINT second;
     SQLUINTEGER fraction;[b]
} TIMESTAMP_STRUCT;[a]

SQL_C_NUMERIC

SQL_NUMERIC_STRUCT

struct tagSQL_NUMERIC_STRUCT {
     SQLCHAR precision;
     SQLSCHAR scale;
     SQLCHAR sign[g];
     SQLCHAR val[SQL_MAX_NUMERIC_LEN];[e], [f]
} SQL_NUMERIC_STRUCT;

SQL_C_GUID

SQLGUID

struct tagSQLGUID {
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} SQLGUID;[k]

图2.6

所以在ODBC的开发过程中不要使用int , float 之类的C语言的实际类型来定义变量而应该使用ODBC定义的数据类型来定义变量,如:SQLINTEGER,SQLFLOAT。