我可能在这里错了,但看起来这里存在相互矛盾的标准。
MySQL将存储的日期时间“0000-00-00 00:00:00”视为等效于NULL。 (更新 - 只是,似乎,如果日期时间被定义为NOT NULL)
但Rose :: DB :: Object对MySQL DATETIME字段使用DateTime,并且尝试从“0000-00-00”设置null DATETIME会在DateTime模块中引发异常。即,我无法使用年0,月0,日0创建DateTime对象,因为这会在DateTime模块中引发异常。
我检查了Rose :: DB :: Object :: Metadata :: Column :: Datetime,在创建条目或检索时无法看到显式处理NULL DateTime的方法。
我错过了什么吗?
即,即使DateTime(Perl模块)不能,Rose :: DB :: Object也能处理NULL datetime(MySQL)字段。
示例代码:
#!/usr/bin/perl
use strict;
use warnings;
use lib 'lib';
use RoseDB::dt_test;
my $dt_entry = RoseDB::dt_test->new();
$dt_entry->date_time_field('0000-00-00');
$dt_entry->save;
1;
__END__
# definition of table as stored in DB
mysql> show create table dt_test \G
*************************** 1. row ***************************
Table: dt_test
Create Table: CREATE TABLE `dt_test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date_time_field` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
使用RoseDB :: dt_test模块:
package RoseDB::dt_test;
use strict;
use warnings;
# this module builds up our DB connection and initializes the connection through:
# __PACKAGE__->register_db
use RoseDB;
use base qw(Rose::DB::Object);
__PACKAGE__->meta->setup (
table => 'dt_test',
columns =>
[
id => { type => 'int', primary_key => 1 },
date_time_field => { type => 'datetime' },
],
);
sub init_db { RoseDB->get_dbh }
1;
当我运行它时,我在tmp.pl第8行收到错误“Invalid datetime:'0000-00-00'”
当我将日期更改为“2010-01-01”时,它按预期工作:
mysql> select * from dt_test\G
*************************** 1. row ***************************
id: 1
date_time_field: 2010-01-01 00:00:00
我终于设法重新创建了NULL MySQL查询示例!
mysql> create table dt_test(dt_test_field datetime not null);
Query OK, 0 rows affected (0.05 sec)
mysql> insert into dt_test values(null);
ERROR 1048 (23000): Column 'dt_test_field' cannot be null
mysql> insert into dt_test values('0000-00-00');
Query OK, 1 row affected (0.00 sec)
mysql> select * from dt_test;
+---------------------+
| dt_test_field |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)
mysql> select * from dt_test where dt_test_field is null;
+---------------------+
| dt_test_field |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)
看起来像使用“NOT NULL”定义日期时间的表定义然后尝试使用MySQL“假null”是问题。我现在太累了不能玩这个,但是我会看到当我在早上改变桌子结构时会发生什么。
答案 0 :(得分:4)
您应该能够将datetime
列设置为文字所需的0000-00-00 00:00:00
值,并将其保存到数据库中:
$o->mycolumn('0000-00-00 00:00:00');
$o->save;
此类“全零”值不会被DateTime
转换为Rose::DB::Object
个对象,而是保留为文字字符串。对于MySQL的DateTime
日期时间字符串,没有语义0000-00-00 00:00:00
对象。
注意:0000-00-00
是有效的date
值,但datetime
(或timestamp
)值必须包含时间:0000-00-00 00:00:00
要将列设置为null,请将undef
作为列值传递:
$o->mycolumn(undef);
当然,如果数据库中的列定义包含NOT NULL
约束,则save()
将无效。
答案 1 :(得分:1)
MySQL允许日期类型不完整(缺少年,月和日)。 '0000-00-00'是一个有效的非NULL MySQL日期。为什么你认为它匹配IS NULL?
$ echo "select date('0000-00-00') is null" | mysql
date('0000-00-00') is null
0
进行比较:
$ echo "select date('0000-00-32') is null" | mysql
date('0000-00-32') is null
1