【问题标题】:Date reverts to 2000-01-01 from ActiveRecord to MySQL从 ActiveRecord 到 MySQL 的日期恢复到 2000-01-01
【发布时间】:2012-10-01 17:19:39
【问题描述】:

我正在尝试在 MySQL 表中节省时间。但是,日期恢复为 2000-01-01。

1.9.2p320 :036 > vv = Visitor.new
 => #<Visitor id: nil, ip_address: nil, num_day_visits: nil, last_visit: nil> 
1.9.2p320 :037 > vv.last_visit = Time.now; vv.ip_address = "3.3.3.3"
 => "3.3.3.3" 
1.9.2p320 :038 > vv.num_day_visits = 1
 => 1 
1.9.2p320 :039 > vv
 => #<Visitor id: nil, ip_address: "3.3.3.3", num_day_visits: 1, last_visit: "2012-10-11 01:31:04"> 
1.9.2p320 :040 > vv.save
  SQL (0.2ms)  BEGIN
  SQL (0.7ms)  INSERT INTO `visitors` (`ip_address`, `last_visit`, `num_day_visits`) VALUES (?, ?, ?)  [["ip_address", "3.3.3.3"], ["last_visit", 2012-10-11 01:31:04 -0400], ["num_day_visits", 1]]
   (0.5ms)  COMMIT
 => true 
1.9.2p320 :042 > vv
 => #<Visitor id: 1199, ip_address: "3.3.3.3", num_day_visits: 1, last_visit: "2012-10-11 01:31:04"> 
1.9.2p320 :043 > Visitor.find(:all,:conditions=>{:ip_address => "3.3.3.3"})
  Visitor Load (1.4ms)  SELECT `visitors`.* FROM `visitors` WHERE `visitors`.`ip_address` = '3.3.3.3'
 => [#<Visitor id: 1199, ip_address: "3.3.3.3", num_day_visits: 1, last_visit: "2000-01-01 05:31:04">] 

所以当我检索记录时,日期是 2000-01-01。

MySQL 中的表:

mysql> describe visitors ;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | int(11)      | NO   | PRI | NULL    | auto_increment |
| ip_address     | varchar(255) | NO   |     | NULL    |                |
| num_day_visits | int(11)      | NO   |     | NULL    |                |
| last_visit     | time         | NO   |     | NULL    |                |
+----------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

更新:我创建了一个玩具表来玩从时间到日期时间的转换。这就是发生的事情:

mysql> select * from example ;
+----+----------+
| id | mytime   |
+----+----------+
|  1 | 11:13:00 |
+----+----------+
1 row in set (0.00 sec)
mysql> alter table example change mytime mytime datetime;
Query OK, 1 row affected, 1 warning (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 1

mysql> select * from example ;
+----+---------------------+
| id | mytime              |
+----+---------------------+
|  1 | 0000-00-00 00:00:00 |
+----+---------------------+
1 row in set (0.00 sec)

这样就破坏了价值。我试图通过将表格更改为时间并使用新行来返回。重新开始:

mysql> select * from example ;
+----+----------+
| id | mytime   |
+----+----------+
|  2 | 11:13:00 |
+----+----------+
1 row in set (0.00 sec)
mysql> ALTER TABLE example CHANGE mytime mytime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP();
ERROR 1067 (42000): Invalid default value for 'mytime'
mysql> ALTER TABLE example CHANGE mytime mytime DATETIME NOT NULL DEFAULT CURRENT_DATE();
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CURRENT_DATE()' at line 1

显然,this is hard

【问题讨论】:

    标签: mysql ruby activerecord time ruby-on-rails-3.1


    【解决方案1】:

    这是因为您的 last_visit 列属于 time 而不是 datetime 类型。最初我假设 mysql 只是使用01-01-2000 作为某种默认日期来表示内部时间字段,但似乎 01-01-2000 是 rails 而不是 mysql。看Represent a time with no date in ruby

    【讨论】:

      【解决方案2】:

      在你的mysql提示符下运行,

      ALTER TABLE 访问者更改 last_visit last_visit 日期时间;

      【讨论】:

      • 我现有的时间会被转换成某个默认日期吗?
      • 试试这个,.....ALTER TABLE visitor CHANGE last_visit last_visit datetime NOT NULL DEFAULT CURRENT_TIMESTAMP;
      【解决方案3】:

      使用AshishBeck 的答案了解我的问题,我只是将时间存储在MySQL 中,而rails 正在为其添加默认的2000-01-01。我试图找到一种方法来更新现有数据以包含日期,使用今天的日期来更新记录。以下是我能得到的。

      假设我们有

      mysql> select * from example ;
      +----+----------+
      | id | mytime   |
      +----+----------+
      |  2 | 11:13:00 |
      +----+----------+
      1 row in set (0.00 sec)
      

      这就是我如何将 mytime 更改为更新的日期时间

      mysql> alter TABLE example ADD  new_time datetime;
      Query OK, 1 row affected (0.04 sec)
      mysql> UPDATE example SET new_time = CONCAT( CURDATE(), " ", mytime );
      Query OK, 1 row affected (0.00 sec)
      Rows matched: 1  Changed: 1  Warnings: 0
      mysql> ALTER TABLE example DROP mytime ;
      Query OK, 1 row affected (0.03 sec)
      Records: 1  Duplicates: 0  Warnings: 0
      
      mysql> ALTER TABLE example CHANGE new_time mytime DATETIME;
      Query OK, 1 row affected (0.04 sec)
      Records: 1  Duplicates: 0  Warnings: 0
      
      mysql> select * from example ;
      +----+---------------------+
      | id | mytime              |
      +----+---------------------+
      |  2 | 2012-10-11 11:13:00 |
      +----+---------------------+
      1 row in set (0.00 sec)
      

      在一个示例中,我找不到一种方法来结合数据更新和更改字段类型。谁有更好的主意?

      【讨论】:

      • 问题是默认值必须是一个常量;它不能是函数或表达式更多信息here。绕过触发 3 个更改和一个更新的一种方法是创建一个新表,例如 create table updated_example as select id, CAST(CONCAT(CURDATE()," ", mytime) AS DATETIME) mytime from example
      • @AshishSaihgal,那么我们必须删除旧表并更改新表的名称。如果没有太多其他列,我想创建一个新表仍然会更快?
      猜你喜欢
      • 1970-01-01
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      相关资源
      最近更新 更多