ODBC:Datetime 字段溢出。秒的小数精度超出了在参数绑定中指定的小数位数。

在使用ODBC将SQL_TIMESTAMP_STRUCT格式的数据保存到MS SQL Server的datetime字段时,报如下错误:

Datetime 字段溢出。秒的小数精度超出了在参数绑定中指定的小数位数。

 C++代码如下:

void execSql(SQLHSTMT hstmt, SQLUINTEGER id, SQL_TIMESTAMP_STRUCT optDtm) {
  SQLRETURN retCode;
  SQLLEN cbId = 0, cbOptDtm = 0;
  
  retCode = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(SQLUINTEGER), 0, &id, 0, &cbId);
  retCode = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, sizeof(optDtm), 0, &optDtm, 0, &cbOptDtm);
  
  SQLWCHAR* sql = (SQLWCHAR*)L"INSERT INTO tb_test(id, opt_dtm) VALUES (?, ?);";
  retCode = SQLPrepare(hstmt, sql, SQL_NTS);
  
  retCode = SQLExecute(hstmt);
}

ODBC驱动:ODBC Driver 17 for SQL Server
opt_dtm:在数据库中的类型为datetime

通过网上查找,说SQLBindParameter中的DecimalDigits是用来设置秒后小数的位数的。datetime是3位,datetime2是7位。

SQLBindParameter的定义如下:

SQLRETURN SQLBindParameter(  
      SQLHSTMT        StatementHandle,  
      SQLUSMALLINT    ParameterNumber,  
      SQLSMALLINT     InputOutputType,  
      SQLSMALLINT     ValueType,  
      SQLSMALLINT     ParameterType,  
      SQLULEN         ColumnSize,  
      SQLSMALLINT     DecimalDigits,  
      SQLPOINTER      ParameterValuePtr,  
      SQLLEN          BufferLength,  
      SQLLEN *        StrLen_or_IndPtr);

 但把代码中DecimalDigits参数的值改成3,还是报一样的错:

retCode = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, sizeof(optDtm), 3, &optDtm, 0, &cbOptDtm);

如果不使用SQL_TIMESTAMP_STRUCT,而使用日期字符串,就可以成功插入,代码如下:

SQLCHAR* optDtm = (SQLCHAR*)"2008-09-09 10:10:10,200";
retCode = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 23, 0, optDtm, 0, &cbOptDtm);

至于为什么使用SQL_TIMESTAMP_STRUCT插入不成功,只能看看以后能不能找到解决办法了。

 

参考文档

C 数据类型
SQL 数据类型
将数据从 C 转换为 SQL 数据类型
SQLBindParameter 函数
Date and Time Improvements (ODBC)
Date and time types 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值