从 SQL 到 C:数字

数字 ODBC SQL 数据类型的标识符如下:

  • SQL_DECIMAL
  • SQL_BIGINT
  • SQL_NUMERIC
  • SQL_REAL
  • SQL_TINYINT
  • SQL_FLOAT
  • SQL_SMALLINT
  • SQL_DOUBLE SQL_INTEGER

下表显示了可将数值 SQL 数据转换为的 ODBC C 数据类型。 有关表中的列和术语的说明,请参阅 将数据从 SQL 转换为 C 数据类型

C 类型标识符 测试 *TargetValuePtr *StrLen_or_IndPtr SQLSTATE
SQL_C_CHAR 字符字节长度 <BufferLength

整 (数,而不是小数) 位数 <BufferLength

与小数) 位数 >相比,整个 (数 = BufferLength
数据

截断的数据

Undefined
数据长度(以字节为单位)

数据长度(以字节为单位)

Undefined
不适用

01004

22003
SQL_C_WCHAR 字符长度 <BufferLength

整 (数,而不是小数) 位数 <BufferLength

与小数) 位数 >相比,整个 (数 = BufferLength
数据

截断的数据

Undefined
数据长度(以字符为单位)

数据长度(以字符为单位)

Undefined
不适用

01004

22003
SQL_C_STINYINT

SQL_C_UTINYINT

SQL_C_TINYINT

SQL_C_SBIGINT

SQL_C_UBIGINT

SQL_C_SSHORT

SQL_C_USHORT

SQL_C_SHORT

SQL_C_SLONG

SQL_C_ULONG

SQL_C_LONG

SQL_C_NUMERIC
在不截断的情况下转换的数据[a]

通过截断小数位数转换的数据[a]

转换数据将导致整个 (丢失,而不是小数) 位数[a]
数据

截断的数据

Undefined
C 数据类型的大小

C 数据类型的大小

Undefined
不适用

01S07

22003
SQL_C_FLOAT

SQL_C_DOUBLE
数据在数字要转换为的数据类型范围内[a]

数据超出了数字要转换为的数据类型的范围[a]
数据

Undefined
C 数据类型的大小

Undefined
不适用

22003
SQL_C_BIT 数据为 0 或 1[a]

数据大于 0、小于 2 且不等于 1[a]

数据小于 0 或大于或等于 2[a]
数据

截断的数据

Undefined
1[b]

1[b]

Undefined
不适用

01S07

22003
SQL_C_BINARY 数据的 <字节长度 = BufferLength

数据 >BufferLength 的字节长度
数据

Undefined
数据长度

Undefined
不适用

22003
SQL_C_INTERVAL_MONTH[c] SQL_C_INTERVAL_YEAR[c] SQL_C_INTERVAL_DAY[c] SQL_C_INTERVAL_HOUR[c] SQL_C_INTERVAL_MINUTE[c] SQL_C_INTERVAL_SECOND[c] 数据未截断

秒小数部分截断

数字的整个部分被截断
数据

截断的数据

Undefined
数据长度(以字节为单位)

数据长度(以字节为单位)

Undefined
不适用

01S07

22015
SQL_C_INTERVAL_YEAR_TO_MONTH SQL_C_INTERVAL_DAY_TO_HOUR SQL_C_INTERVAL_DAY_TO_MINUTE SQL_C_INTERVAL_DAY_TO_SECOND SQL_C_INTERVAL_HOUR_TO_MINUTE SQL_C_INTERVAL_HOUR_TO_SECOND 数字的整个部分被截断 Undefined Undefined 22015

[a] 对于此转换, 将忽略 BufferLength 的值。 驱动程序假定 *TargetValuePtr 的大小是 C 数据类型的大小。

[b] 这是相应 C 数据类型的大小。

[c] 仅支持确切的数值数据类型 (SQL_DECIMAL、SQL_NUMERIC、SQL_TINYINT、SQL_SMALLINT、SQL_INTEGER和SQL_BIGINT) 。 近似数值数据类型不支持 (SQL_REAL、SQL_FLOAT或SQL_DOUBLE) 。

SQL_C_NUMERIC 和 SQLSetDescField

需要 SQLSetDescField 函数 才能使用SQL_C_NUMERIC值执行手动绑定。 (请注意,SQLSetDescField 已添加到 ODBC 3.0.) 若要执行手动绑定,必须先获取描述符句柄。

if (fCType == SQL_C_NUMERIC) {   
   // special processing required for NUMERIC to get right scale & precision  
   // Modify the fields in the implicit application parameter descriptor  
   SQLHDESC hdesc=NULL;  
  
   // Use SQL_ATTR_APP_ROW_DESC for calls to SQLBindCol()  
   // Use SQL_ATTR_APP_PARAM_DESC for calls to SQLBindParameter()  
   //  
   // retcode = SQLGetStmtAttr(hstmt, SQL_ATTR_APP_ROW_DESC, &hdesc, 0, NULL);  
   retcode = SQLGetStmtAttr(hstmt, SQL_ATTR_APP_PARAM_DESC, &hdesc, 0, NULL);  
   if (!ODBC_CALL_SUCCESS(retcode)) {  
      printf ("\nSQLGetStmtAttr failed");  
      i = 1;  
      sqlstate[7] = '\0';  
      while (SQLGetDiagRec(SQL_HANDLE_STMT, hstmt, i, sqlstate, &NativeError, wrkbuf, sizeof(wrkbuf), &len) != SQL_NO_DATA) {  
         printf("\niTestCase = %d Failed...Precision = %d, Scale = %d\nNativeError=%d, State=%s, \n  Message=%s",   
            iTestCase, Precision, Scale, NativeError, sqlstate, wrkbuf);  
         i++;  
      }  
      continue;  
   }  
   retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_TYPE, (SQLPOINTER) SQL_C_NUMERIC, 0);  
   if (!ODBC_CALL_SUCCESS(retcode))  
      goto error;  
   retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_PRECISION, (SQLPOINTER)num.precision, 0);  
   if (!ODBC_CALL_SUCCESS(retcode))  
      goto error;  
   retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_SCALE, (SQLPOINTER)num.scale, 0);  
   if (!ODBC_CALL_SUCCESS(retcode))  
      goto error;  
   retcode = SQLSetDescField(hdesc, iCol, SQL_DESC_DATA_PTR, (SQLPOINTER) &(num), sizeof(num));