从 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));