对单独的 DATE 和 TIME 使用相同的缓冲区
Use the same buffer for separate DATE and TIME
我正在使用 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
是一个有效的连接。本例中的 table mytable
只包含一个 DATE
类型和一个 TIME
类型。
)
这是 TIME
type 的自然表示 - 顾名思义,它只保存时间,这是表示 time 大于 a 的自然方式日。正如文档所建议的那样,它确实对较小的值使用 HH:MM:SS
。
因为 TIME
does not care about shenanigans like leap seconds,要排除全天,只需要 tm_hour%24
。但是,为了允许像 DST 转换这样的恶作剧,您只需将 TIME
添加到特定月份的起点并使用股票函数进行 DATETIME
算术。
@:
试图超越 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);
}
如您所见,它总是用完整个结构(显然,以便相关功能始终按预期工作)。
我正在使用 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
是一个有效的连接。本例中的 table mytable
只包含一个 DATE
类型和一个 TIME
类型。
)
这是 TIME
type 的自然表示 - 顾名思义,它只保存时间,这是表示 time 大于 a 的自然方式日。正如文档所建议的那样,它确实对较小的值使用 HH:MM:SS
。
因为 TIME
does not care about shenanigans like leap seconds,要排除全天,只需要 tm_hour%24
。但是,为了允许像 DST 转换这样的恶作剧,您只需将 TIME
添加到特定月份的起点并使用股票函数进行 DATETIME
算术。
@
试图超越 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);
}
如您所见,它总是用完整个结构(显然,以便相关功能始终按预期工作)。