3

ここで間違っている可能性がありますが、ここには矛盾する基準があるようです。

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 を明示的に処理する方法がわかりません。

何か不足していますか?

つまり、Rose::DB::Object は NULL 日時 (MySQL) フィールドを処理できますが、DateTime (Perl モジュール) は処理できません。

サンプルコード:

#!/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;

実行すると、「Invalid datetime: '0000-00-00' at tmp.pl line 8」というエラーが表示されます。

日付を「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」を使用しようとすることが問題です。今は疲れすぎてこれで遊ぶことはできませんが、朝にテーブル構造を変更するとどうなるか見てみましょう.

4

2 に答える 2

4

datetime列を文字通りの目的の0000-00-00 00:00:00値に設定し、データベースに保存できるはずです。

$o->mycolumn('0000-00-00 00:00:00');
$o->save;

このような「すべてゼロ」の値は、DateTimeによってオブジェクトに変換されるRose::DB::Objectのではなく、リテラル文字列として残ります。DateTimeMySQLの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()ません。

于 2010-01-27T04:20:47.583 に答える
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
于 2010-01-27T03:34:20.527 に答える