对于单独的DATE和TIME使用相同的缓冲区

时间:2015-02-21 21:11:37

标签: mysql c mysql-connector

我正在使用MySQL C api和准备好的语句。发出带有TIME字段的INSERT查询时,结果为HHH:MM:SS格式,其中小时数是本月经过的小时数。例如,如果日期是2015-02-21,时间是21:30:00,那么时间将显示为525:30:00但我想使用HH:MM:SS格式(例如21:30) :00),这将是一天中的实际时间。

sbind[3].buffer_type=MYSQL_TYPE_DATE;
sbind[3].buffer= (char *)&ts; // Pointer to a MYSQL_TIME data structure
sbind[3].is_null= 0;
sbind[3].length= 0;

sbind[4] = sbind[3];
sbind[4].buffer_type=MYSQL_TYPE_TIME;

mysql_stmt_bind_param(stmt, sbind); // sbind is an array of MYSQL_BIND structures

ts.year= 1900+tm_info->tm_year; // tm_info is a pointer to a tm structure
ts.month= 1+tm_info->tm_mon;
ts.day= tm_info->tm_mday;

ts.hour= tm_info->tm_hour;
ts.minute= tm_info->tm_min;
ts.second= tm_info->tm_sec;

此代码将日期字段准备为yyyy-mm-dd,并在tm_info中填入日期。同样,它将对时间字段执行相同的操作,但采用HHH:MM:SS格式。

一种不合时宜的方式是使用单独的MYSQL_TIME结构,但我的目标是以更优雅的方式来处理它。

编辑:此处我已包含相关的客户端代码

MYSQL_TIME  ts;
MYSQL_STMT *stmt;
MYSQL_BIND sbind[2];

...

char query[QUERY_BUFFER_SIZE];
strcpy(query, "INSERT INTO `mytable` (date,time) VALUES(?,?)");
if(mysql_stmt_prepare(stmt, query, strlen(query))){
    return mysql_stmt_errno(stmt);
}

...

time_t rawtime;
time(&rawtime); // get current time
struct tm *tm_info = localtime ( &rawtime );

...

memset(sbind,0,sizeof(sbind));

sbind[0].buffer_type=MYSQL_TYPE_DATE;
sbind[0].buffer= (char *)&ts; // Pointer to a MYSQL_TIME data structure
sbind[0].is_null= 0;
sbind[0].length= 0;

sbind[1] = sbind[0];
sbind[1].buffer_type=MYSQL_TYPE_TIME;

mysql_stmt_bind_param(stmt, sbind); // sbind is an array of MYSQL_BIND structures

ts.year= 1900+tm_info->tm_year; // tm_info is a pointer to a tm structure
ts.month= 1+tm_info->tm_mon;
ts.day= tm_info->tm_mday;

ts.hour= tm_info->tm_hour;
ts.minute= tm_info->tm_min;
ts.second= tm_info->tm_sec;

if(mysql_stmt_execute(stmt)){
    return mysql_stmt_errno(stmt);
}

这假设mysql是有效连接。在这种情况下,表格mytable仅包含DATE类型和TIME类型。

1 个答案:

答案 0 :(得分:1)

这是TIME type的自然表示 - 顾名思义,它只保留时间,这是表达时间大于一天的自然方式。正如文档所示,它确实使用HH:MM:SS来表示较小的值。

TIME does not care about shenanigans like leap seconds开始,要排除整天,请点击tm_hour%24。但是,为了允许像DST过渡这样的恶作剧,你无需做任何事情,只需将TIME添加到特定月份的起点,并使用股票函数进行DATETIME算术运算。

@ c45602234

试图超越libmysql失败(mysql-connector-c-6.1.5/libmysql/libmysql.c:1964):

static void store_param_date(NET *net, MYSQL_BIND *param)
{
  MYSQL_TIME tm= *((MYSQL_TIME *) param->buffer);
  tm.hour= tm.minute= tm.second= tm.second_part= 0;
  net_store_datetime(net, &tm);
}

正如您所看到的,它总是耗尽整个结构(显然,相关功能始终按预期工作)。