首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Rose::DB::Object和MySQL设置空datetime

问使用Rose::DB::Object和MySQL设置空datetime
EN

Stack Overflow用户
提问于 2010-01-27 11:23:40
回答 2查看 1.4K关注 0票数 3

我可能在这里错了,但看起来这里有相互冲突的标准。

MySQL将存储的日期时间"0000-00-00 00:00:00“视为等同于NULL。(如果datetime定义为NOT NULL,则似乎仅更新)

但是Rose::DB::Object对MySQL日期时间字段使用了DateTime,并且试图从"0000-00-00“设置一个null日期时间会在DATETIME模块中抛出一个异常。也就是说,我不能创建年份为0,月份为0,日期为0的DateTime对象,因为这会在DateTime模块中抛出异常。

我检查了Rose::DB::Object::Metadata::Column:: DateTime,但在创建条目或检索条目时看不到显式处理空DateTime的方法。

我是不是遗漏了什么?

即使datetime (Perl模块)不能处理空日期时间(MySQL)字段,也可以使用can::DB::Object。

示例代码:

代码语言:javascript
复制
#!/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模块为:

代码语言:javascript
复制
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“时,它按预期工作:

代码语言:javascript
复制
mysql> select * from dt_test\G
*************************** 1. row ***************************
             id: 1
date_time_field: 2010-01-01 00:00:00

我最终设法重新创建了空的MySQL查询示例!

代码语言:javascript
复制
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 "fake null”。我现在太累了,不能玩这个游戏,但我会看看当我早上改变表结构时会发生什么。

EN

回答 2

Stack Overflow用户

发布于 2010-01-27 12:20:48

您应该能够将datetime列设置为文字所需的0000-00-00 00:00:00值,并将其保存到数据库中:

代码语言:javascript
复制
$o->mycolumn('0000-00-00 00:00:00');
$o->save;

这样的“全零”值不会被Rose::DB::Object转换为DateTime对象,而是保留为文字字符串。对于MySQL的0000-00-00 00:00:00日期时间字符串,没有等价的语义DateTime对象。

注意:0000-00-00是一个有效的Time值,但datetime (或timestamp)值必须包含date:0000-00-00 00:00:00

要将列设置为null,请将undef作为列值传递:

代码语言:javascript
复制
$o->mycolumn(undef);

当然,如果数据库中的列定义包含NOT NULL约束,则save()将无法工作。

票数 4
EN

Stack Overflow用户

发布于 2010-01-27 11:34:21

MySQL允许日期类型不完整(缺少年、月或日)。“0000-00-00”是有效的非NULL MySQL日期。为什么你认为它匹配的是空的?

代码语言:javascript
复制
$ echo "select date('0000-00-00') is null" | mysql
date('0000-00-00') is null
0

作为比较:

代码语言:javascript
复制
$ echo "select date('0000-00-32') is null" | mysql
date('0000-00-32') is null
1
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2144377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档