分享方式:


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
資料

截斷的資料

未定義
以位元組為單位的資料長度

以位元組為單位的資料長度

未定義
n/a

01004

22003
SQL_C_WCHAR 字元長度 < BufferLength

整數數(而不是小數)位數 < BufferLength

整數數 (而不是小數) 位數 > = BufferLength
資料

截斷的資料

未定義
以字元為單位的資料長度

以字元為單位的資料長度

未定義
n/a

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]
資料

截斷的資料

未定義
C 資料類型的大小

C 資料類型的大小

未定義
n/a

01S07

22003
SQL_C_FLOAT

SQL_C_DOUBLE
資料位於要轉換數位的資料類型範圍內[a]

資料超出要轉換數位的資料類型範圍[a]
資料

未定義
C 資料類型的大小

未定義
n/a

22003
SQL_C_BIT 資料為 0 或 1[a]

資料大於 0、小於 2 且不等於 1[a]

資料小於 0 或大於或等於 2[a]
資料

截斷的資料

未定義
1[b]

1[b]

未定義
n/a

01S07

22003
SQL_C_BINARY 位元組長度的資料 < = BufferLength

資料 > BufferLength 的位元組長度
資料

未定義
資料長度

未定義
n/a

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] 未截斷的資料

小數秒部分截斷

截斷數位的整個部分
資料

截斷的資料

未定義
以位元組為單位的資料長度

以位元組為單位的資料長度

未定義
n/a

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 截斷數位的整個部分 未定義 未定義 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));