有没有办法更改默认的日期输入格式
Is there a way to change the default date input format
我有一个数据源,我从那里提取了一些字段,在这些字段中有一些 date 字段,源发送它们的值是这样的
#DD/MM/YYYY#
几乎所有的字段都可以不加修改地发送到查询中,当然除了这个。
我编写了一个程序,它从互联网连接获取数据并将其发送到 MySQL 服务器,它会按原样发送所有内容,我敢肯定,因为我在 [=52] 中启用了常规日志记录=] 服务器,我可以看到所有查询都是正确的,除了带有日期字段的查询。
我想避免以这种方式解析字段,因为它是用 c 编写的,所以需要做很多工作,但如果没有办法,我理解并当然会接受它作为答案。
举个例子,假设我们有以下内容
INSERT INTO sometable VALUES ('#12/10/2015#', ... OTHER_VALUES ..., '#11/10/2015#');
在这种情况下,我使用 libmysqlclient
中的 mysql_query()
将整个内容作为查询发送。
在其他情况下,我可以将消息的各个部分拆分为指令和参数之类的内容,如下所示
iab A,B,C,#12/10/2015#,X,Y,#11/10/2015#
这可能意味着 INSERT INTO table_a_something_b_whatever VALUES
,当然在这种情况下,我捕获所有参数并发送一个包含 VALUES
列表的查询。同样在这种情况下,这很简单,因为我可以像这样处理日期
char date[] = "#11/10/2015#";
int day;
int month;
int year;
if (sscanf(date, "#%d/%d/%d#", &day, &month, &year) == 3)
{
/* it's fine, build a sane YYYY-MM-DD */
}
所以问题是:
- 如何告诉 MySQL 服务器日期字段的格式?
对的澄清:
不一定INSERT
,比这更复杂。它们有时是包含所有参数的查询,有时它们只是参数,我必须构建查询。这是一个巨大的混乱,但我对此无能为力,因为它是一个付费数据库,我必须暂时使用它。
真正的问题是当查询来自源并且必须按原样发送时,因为这样可能会出现很多情况。当我将参数一一拆分时,没有真正的问题,因为解析上述日期格式并生成 MySQL 的适当值非常简单。
您可以在 MySQL 中使用 STR_TO_DATE()
:
SELECT STR_TO_DATE('#08/10/2015#','#%d/%m%Y#');
将此作为您的 INSERT
流程的一部分:
INSERT INTO yourtable (yourdatecolumn) VALUES (STR_TO_DATE('#08/10/2015#','#%d/%m%Y#'));
目前我唯一能想到的就是将您的列类型从 DateTime 更改为 varchar 并使用 BEFORE INSERT
触发器来修复 "wrong" 日期。
像这样:
DELIMITER //
CREATE TRIGGER t1 BEFORE INSERT on myTable FOR EACH ROW
BEGIN
IF (NEW.myDate regexp '#[[:digit:]]+\/[[:digit:]]+\/[[:digit:]]+#') THEN
SET NEW.myDate = STR_TO_DATE(NEW.myDate,'#%d/%m/%Y#');
END IF;
END; //
DELIMITER ;
如果您只需要 运行 有问题的导入一次,请使用触发器从插入中生成 "proper" dateTimeColumn - 然后删除 varchar-column:
('myDate' := varchar 列之后删除;`'myRealDate' := DateTime 列之后保留)
DELIMITER //
CREATE TRIGGER t1 BEFORE INSERT on myTable FOR EACH ROW
BEGIN
IF (NEW.myDate regexp '#[[:digit:]]+\/[[:digit:]]+\/[[:digit:]]+#') THEN
SET NEW.myRealDate = STR_TO_DATE(NEW.myDate,'#%d/%m/%Y#');
else
#assume a valid date representation
SET NEW.myRealDate = NEW.myDate;
END IF;
END; //
DELIMITER ;
不幸的是,您不能使用触发器处理日期时间列本身,因为 mysql 已经弄乱了 NEW.myDate
-列。
我有一个数据源,我从那里提取了一些字段,在这些字段中有一些 date 字段,源发送它们的值是这样的
#DD/MM/YYYY#
几乎所有的字段都可以不加修改地发送到查询中,当然除了这个。
我编写了一个程序,它从互联网连接获取数据并将其发送到 MySQL 服务器,它会按原样发送所有内容,我敢肯定,因为我在 [=52] 中启用了常规日志记录=] 服务器,我可以看到所有查询都是正确的,除了带有日期字段的查询。
我想避免以这种方式解析字段,因为它是用 c 编写的,所以需要做很多工作,但如果没有办法,我理解并当然会接受它作为答案。
举个例子,假设我们有以下内容
INSERT INTO sometable VALUES ('#12/10/2015#', ... OTHER_VALUES ..., '#11/10/2015#');
在这种情况下,我使用 libmysqlclient
中的 mysql_query()
将整个内容作为查询发送。
在其他情况下,我可以将消息的各个部分拆分为指令和参数之类的内容,如下所示
iab A,B,C,#12/10/2015#,X,Y,#11/10/2015#
这可能意味着 INSERT INTO table_a_something_b_whatever VALUES
,当然在这种情况下,我捕获所有参数并发送一个包含 VALUES
列表的查询。同样在这种情况下,这很简单,因为我可以像这样处理日期
char date[] = "#11/10/2015#";
int day;
int month;
int year;
if (sscanf(date, "#%d/%d/%d#", &day, &month, &year) == 3)
{
/* it's fine, build a sane YYYY-MM-DD */
}
所以问题是:
- 如何告诉 MySQL 服务器日期字段的格式?
对的澄清:
不一定INSERT
,比这更复杂。它们有时是包含所有参数的查询,有时它们只是参数,我必须构建查询。这是一个巨大的混乱,但我对此无能为力,因为它是一个付费数据库,我必须暂时使用它。
真正的问题是当查询来自源并且必须按原样发送时,因为这样可能会出现很多情况。当我将参数一一拆分时,没有真正的问题,因为解析上述日期格式并生成 MySQL 的适当值非常简单。
您可以在 MySQL 中使用 STR_TO_DATE()
:
SELECT STR_TO_DATE('#08/10/2015#','#%d/%m%Y#');
将此作为您的 INSERT
流程的一部分:
INSERT INTO yourtable (yourdatecolumn) VALUES (STR_TO_DATE('#08/10/2015#','#%d/%m%Y#'));
目前我唯一能想到的就是将您的列类型从 DateTime 更改为 varchar 并使用 BEFORE INSERT
触发器来修复 "wrong" 日期。
像这样:
DELIMITER //
CREATE TRIGGER t1 BEFORE INSERT on myTable FOR EACH ROW
BEGIN
IF (NEW.myDate regexp '#[[:digit:]]+\/[[:digit:]]+\/[[:digit:]]+#') THEN
SET NEW.myDate = STR_TO_DATE(NEW.myDate,'#%d/%m/%Y#');
END IF;
END; //
DELIMITER ;
如果您只需要 运行 有问题的导入一次,请使用触发器从插入中生成 "proper" dateTimeColumn - 然后删除 varchar-column:
('myDate' := varchar 列之后删除;`'myRealDate' := DateTime 列之后保留)
DELIMITER //
CREATE TRIGGER t1 BEFORE INSERT on myTable FOR EACH ROW
BEGIN
IF (NEW.myDate regexp '#[[:digit:]]+\/[[:digit:]]+\/[[:digit:]]+#') THEN
SET NEW.myRealDate = STR_TO_DATE(NEW.myDate,'#%d/%m/%Y#');
else
#assume a valid date representation
SET NEW.myRealDate = NEW.myDate;
END IF;
END; //
DELIMITER ;
不幸的是,您不能使用触发器处理日期时间列本身,因为 mysql 已经弄乱了 NEW.myDate
-列。