請問一個mysql抓取不等於0000-00-00的問題
时间:2010-07-12
来源:互联网
请教各位前辈,如果我要抓某日期栏位的值不等於NULL或0000-00-00,请问我该怎样抓
以下是我目前使用的方法,而且也正常可以使用,不过我想请问这样是正确的做法吗:
SELECT
*
FROM
`a`
WHERE
`d` IS NOT NULL
AND `d` <> '0000-00-00'
谢谢各位
以下是我目前使用的方法,而且也正常可以使用,不过我想请问这样是正确的做法吗:
SELECT
*
FROM
`a`
WHERE
`d` IS NOT NULL
AND `d` <> '0000-00-00'
谢谢各位
作者: itw 发布时间: 2010-07-12
引用自: itw 於 2010-07-12 11:58
请教各位前辈,如果我要抓某日期栏位的值不等於NULL或0000-00-00,请问我该怎样抓
以下是我目前使用的方法,而且也正常可以使用,不过我想请问这样是正确的做法吗:
SELECT
*
FROM
`a`
WHERE
`d` IS NOT NULL
AND `d` <> '0000-00-00'
谢谢各位
以下是我目前使用的方法,而且也正常可以使用,不过我想请问这样是正确的做法吗:
SELECT
*
FROM
`a`
WHERE
`d` IS NOT NULL
AND `d` <> '0000-00-00'
谢谢各位
最好还是要把好关,前面的程式要把日期栏位处理好. 不然以后你的系统会因为这些错误的日期资料付出很大的代价,若是跟商务有关的话,更是要谨慎.
'0000-00-00' 是format 没设定好产生的结果,建议你把这些都update为NULL. 但还是建议你最好检查一下前面的程式,尽量不要让这种情形发生,
要是不确定就是输入NULL.若是user有输入,但是因为程式的问题,变为'0000-00-00', 那很容易产生纠纷的.
年纪大了,讲话有点囉唆,多多包涵.
作者: bunko 发布时间: 2010-07-12
做了一些实验:
mysql> create table datefoo (realdate date, foodate char(10));
mysql> select * from datefoo;
+------------+------------+
| realdate | foodate |
+------------+------------+
| 0000-00-00 | 0000-00-00 |
| 0000-00-00 | 1900-02-29 |
| 0000-00-00 | 2100-02-30 |
| 0000-00-00 | 2100-02-31 |
| NULL | 2100-02-32 |
| NULL | bad format |
| NULL | InvaildDat |
| NULL | 2100-14-01 |
+------------+------------+
8 rows in set (0.00 sec)
从这实验可以看出一些端倪, 0000-00-00 与 NULL 都是代表Invalid Date, 但是会存NULL的就是很直接就能判断是错误的, 如 32日,当然45日也会一样;
或是14月;或是根本就是字串;或是format字串错误.
0000-00-00 的有直接指定就是要存0000-00-00,或是第一道判断(return null)尚未能决定,但是第二道判断判定有误.如2月30日,2月31日;或是非闰年的2月29日.
mysql> create table datefoo (realdate date, foodate char(10));
程式码: sql
mysql> INSERT INTO datefoo VALUES
(str_to_date('0000-00-00','%Y-%m-%d'), '0000-00-00' ),
(str_to_date('1900-02-29','%Y-%m-%d'), '1900-02-29'),
(str_to_date('2100-02-30','%Y-%m-%d'), '2100-02-30'),
(str_to_date('2100-02-31','%Y-%m-%d'), '2100-02-31'),
(str_to_date('2100-02-32','%Y-%m-%d'), '2100-02-32'),
(str_to_date('2010-07-12','abc'), 'bad format'),
(str_to_date('Invaild Date','%Y-%m-%d'), 'InvaildDat'),
(str_to_date('2100-14-01','%Y-%m-%d'), '2100-14-01');
mysql> select * from datefoo;
+------------+------------+
| realdate | foodate |
+------------+------------+
| 0000-00-00 | 0000-00-00 |
| 0000-00-00 | 1900-02-29 |
| 0000-00-00 | 2100-02-30 |
| 0000-00-00 | 2100-02-31 |
| NULL | 2100-02-32 |
| NULL | bad format |
| NULL | InvaildDat |
| NULL | 2100-14-01 |
+------------+------------+
8 rows in set (0.00 sec)
从这实验可以看出一些端倪, 0000-00-00 与 NULL 都是代表Invalid Date, 但是会存NULL的就是很直接就能判断是错误的, 如 32日,当然45日也会一样;
或是14月;或是根本就是字串;或是format字串错误.
0000-00-00 的有直接指定就是要存0000-00-00,或是第一道判断(return null)尚未能决定,但是第二道判断判定有误.如2月30日,2月31日;或是非闰年的2月29日.
作者: bunko 发布时间: 2010-07-12
推测楼主可能就是直接insert into 进table,进而产生0000-00-00
mysql> insert into datefoo values
-> ('2007-02-29','2007-02-29');
Query OK, 1 row affected, 1 warning (0.00 sec)
会产生0000-00-00.
MySQL有str_to_date(), 可是刚才我们也使用此函数,但是 1900-02-29 也是进去mysql后,被转为0000-00-00了.
我们再试一下str_to_date(),
mysql> insert into datefoo values(str_to_date('2010-04-31','%Y-%m-%d'), '2010-04-31');
Query OK, 1 row affected, 1 warning (0.03 sec)
mysql> select * from datefoo
-> where foodate='2007-02-29' or foodate='2010-04-31';
+------------+------------+
| realdate | foodate |
+------------+------------+
| 0000-00-00 | 2007-02-29 |
| 0000-00-00 | 2010-04-31 |
+------------+------------+
2 rows in set (0.10 sec)
由上面的结果可以得知,str_to_date()并不会帮我们完全判断日期是否正确,只能做到部份功能,
下面的实验也能看出str_to_date()的限制所在.
mysql> select str_to_date('2010-04-31','%Y-%m-%d');
+--------------------------------------+
| str_to_date('2010-04-31','%Y-%m-%d') |
+--------------------------------------+
| 2010-04-31 |
+--------------------------------------+
1 row in set (0.00 sec)
mysql> select str_to_date('2010-04-32','%Y-%m-%d');
+--------------------------------------+
| str_to_date('2010-04-32','%Y-%m-%d') |
+--------------------------------------+
| NULL |
+--------------------------------------+
1 row in set, 1 warning (0.00 sec)
===============================
为了加强日期检查的功能,我们发展自己的函数来增强.
以下为测试过程:
先修改一下测试的table.
mysql> ALTER TABLE datefoo ADD COLUMN isdate BOOLEAN;
Query OK, 10 rows affected (0.14 sec)
以下为检查是否为valid date的函数,mychk_date()
-------------------------------------------
DELIMITER $$
DROP FUNCTION IF EXISTS `mysample`.`mychk_date`$$
CREATE FUNCTION `mysample`.`mychk_date` (indate date) RETURNS boolean
BEGIN
DECLARE rtn boolean;
IF indate = DATE_SUB(DATE_ADD(indate,INTERVAL 1 DAY),INTERVAL 1 DAY) THEN
SET rtn = TRUE;
ELSE
SET rtn = FALSE;
END IF;
RETURN rtn;
END$$
DELIMITER ;
-------------------------------------------
INSERT 一些正常的日期进去datefoo,好进行测试.
mysql> insert into datefoo(realdate,foodate)
-> values(now(),'2010-07-12');
mysql> insert into datefoo(realdate,foodate) values(str_to_date('2010-06-25','%Y-%m-%d'),'2010-06-25');
mysql> select * from datefoo;
+------------+------------+--------+
| realdate | foodate | isdate |
+------------+------------+--------+
| 0000-00-00 | 0000-00-00 | NULL |
| 0000-00-00 | 1900-02-29 | NULL |
| 0000-00-00 | 2100-02-30 | NULL |
| 0000-00-00 | 2100-02-31 | NULL |
| NULL | 2100-02-32 | NULL |
| NULL | bad format | NULL |
| NULL | InvaildDat | NULL |
| NULL | 2100-14-01 | NULL |
| 0000-00-00 | 2007-02-29 | NULL |
| 0000-00-00 | 2010-04-31 | NULL |
| 2010-07-12 | 2010-07-12 | NULL |
| 2010-06-25 | 2010-06-25 | NULL |
+------------+------------+--------+
12 rows in set (0.01 sec)
接下来就使用mychk_date()来进行检查.
mysql> UPDATE datefoo SET isdate=mychk_date(realdate);
Query OK, 12 rows affected, 6 warnings (0.04 sec)
Rows matched: 12 Changed: 12 Warnings: 0
mysql> select * from datefoo;
+------------+------------+--------+
| realdate | foodate | isdate |
+------------+------------+--------+
| 0000-00-00 | 0000-00-00 | 0 |
| 0000-00-00 | 1900-02-29 | 0 |
| 0000-00-00 | 2100-02-30 | 0 |
| 0000-00-00 | 2100-02-31 | 0 |
| NULL | 2100-02-32 | 0 |
| NULL | bad format | 0 |
| NULL | InvaildDat | 0 |
| NULL | 2100-14-01 | 0 |
| 0000-00-00 | 2007-02-29 | 0 |
| 0000-00-00 | 2010-04-31 | 0 |
| 2010-07-12 | 2010-07-12 | 1 |
| 2010-06-25 | 2010-06-25 | 1 |
+------------+------------+--------+
12 rows in set (0.00 sec)
使用mychk_date()进行日期检查.
mysql> SELECT mychk_date(str_to_date('2010-02-29','%Y-%m-%d'));
+--------------------------------------------------+
| mychk_date(str_to_date('2010-02-29','%Y-%m-%d')) |
+--------------------------------------------------+
| 0 |
+--------------------------------------------------+
1 row in set, 2 warnings (0.00 sec)
mysql> SELECT mychk_date(str_to_date('2010-07-12','%Y-%m-%d'));
+--------------------------------------------------+
| mychk_date(str_to_date('2010-07-12','%Y-%m-%d')) |
+--------------------------------------------------+
| 1 |
+--------------------------------------------------+
1 row in set (0.01 sec)
*********************************************************
接下来我们还要再发展一个检查string是否能转换为valid date的函数.
其实就是把刚才的mychk_date()加工一下就可以了.
函数如下:
-------------------------------------------------------
DELIMITER $$
DROP FUNCTION IF EXISTS `mysample`.`mychk_str_date`$$
CREATE FUNCTION `mysample`.`mychk_str_date` (strdate char(10)) RETURNS boolean
BEGIN
DECLARE rtn boolean;
DECLARE indate DATE;
SET indate = STR_TO_DATE(strdate,'%Y-%m-%d');
IF indate = DATE_SUB(DATE_ADD(indate,INTERVAL 1 DAY),INTERVAL 1 DAY) THEN
SET rtn = TRUE;
ELSE
SET rtn = FALSE;
END IF;
RETURN rtn;
END$$
DELIMITER ;
-------------------------------------------------------
修改一下datefoo,再增加一个栏位.
mysql> ALTER TABLE datefoo ADD COLUMN isdate2 BOOLEAN;
mysql> UPDATE datefoo SET isdate2=mychk_str_date(foodate);
Query OK, 12 rows affected, 15 warnings (0.00 sec)
Rows matched: 12 Changed: 12 Warnings: 5
mysql> SELECT * FROM datefoo;
+------------+------------+--------+---------+
| realdate | foodate | isdate | isdate2 |
+------------+------------+--------+---------+
| 0000-00-00 | 0000-00-00 | 0 | 0 |
| 0000-00-00 | 1900-02-29 | 0 | 0 |
| 0000-00-00 | 2100-02-30 | 0 | 0 |
| 0000-00-00 | 2100-02-31 | 0 | 0 |
| NULL | 2100-02-32 | 0 | 0 |
| NULL | bad format | 0 | 0 |
| NULL | InvaildDat | 0 | 0 |
| NULL | 2100-14-01 | 0 | 0 |
| 0000-00-00 | 2007-02-29 | 0 | 0 |
| 0000-00-00 | 2010-04-31 | 0 | 0 |
| 2010-07-12 | 2010-07-12 | 1 | 1 |
| 2010-06-25 | 2010-06-25 | 1 | 1 |
+------------+------------+--------+---------+
12 rows in set (0.00 sec)
mysql> SELECT mychk_str_date('2010-02-29');
+------------------------------+
| mychk_str_date('2010-02-29') |
+------------------------------+
| 0 |
+------------------------------+
1 row in set, 2 warnings (0.00 sec)
mysql> SELECT mychk_str_date('2010-05-38');
+------------------------------+
| mychk_str_date('2010-05-38') |
+------------------------------+
| 0 |
+------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> SELECT mychk_str_date('2010-07-12');
+------------------------------+
| mychk_str_date('2010-07-12') |
+------------------------------+
| 1 |
+------------------------------+
1 row in set (0.00 sec)
经过以上的实验,我们的mychk_str_date()可以将输入的string检查是否是正确的日期.
可以先行使用mychk_str_date()来检查,正确时再输入,不正确时就可以通知使用者.
PHP或是其他语言均可呼叫此MySQL函数,如同其他函数.
作者: bunko 发布时间: 2010-07-12
事实上可以简单一点....
就是将 mysql 的 sql-mode 设定为严格模式..
请参考这个连结里的资料...
http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#server-sql-mode
尤其关於 NO_ZERO_DATE , NO_ZERO_IN_DATE , ALLOW_INVALID_DATES 等...
会直接於遇到不合法的日期格式时候放弃该段 insert or update SQL
另外关於 MySQL 的 Date Time 相关的资讯建议阅读这个..
http://dev.mysql.com/doc/refman/5.1/zh/column-types.html#date-and-time-types
就是将 mysql 的 sql-mode 设定为严格模式..
请参考这个连结里的资料...
http://dev.mysql.com/doc/refman/5.1/zh/database-administration.html#server-sql-mode
尤其关於 NO_ZERO_DATE , NO_ZERO_IN_DATE , ALLOW_INVALID_DATES 等...
会直接於遇到不合法的日期格式时候放弃该段 insert or update SQL
另外关於 MySQL 的 Date Time 相关的资讯建议阅读这个..
http://dev.mysql.com/doc/refman/5.1/zh/column-types.html#date-and-time-types
作者: Darkhero 发布时间: 2010-07-13
谢谢bunko兄和Darkhero兄的热心指导。
我先来好好的研究一下
我先来好好的研究一下
作者: itw 发布时间: 2010-07-13
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28