【问题标题】:MySQL NOW() in Doctrine DBAL insert?Doctrine DBAL 中的 MySQL NOW() 插入?
【发布时间】:2015-07-17 10:29:01
【问题描述】:

我盯着http://doctrine-dbal.readthedocs.org/en/latest/reference/data-retrieval-and-manipulation.html#insert

我希望能够做类似的事情

$db->insert('mytable', [
  'foo' => 'bar',
  'created_on' => new MagicThatMakesNowWork()
]);

这不可能吗?我见过的最好的解决方案是使用 PHP 在设置时区的同时获取日期时间,这不太理想。由于某种原因,似乎只有 ORM 或查询构建器可以处理表达式。我知道在 Zend 中我可以执行类似 new Zend_Db_Expr('NOW()') 的操作,并且它通过对象类型知道不要在构建的查询中引用 NOW()。无需查询构建器或 ORM。

不确定这是不可能的还是没有很好的记录。 Doctrine DBAL: Updating timestamp field with 'NOW()' value 上的第二个答案在 types 数组中显示了一个随机字符串 datetime,这看起来也很奇怪/不好。

【问题讨论】:

  • 如果你把CURRENT_TIMESTAMP()放在那里呢?
  • 你应该试试 Doctrine TimeStampable...github.com/l3pp4rd/DoctrineExtensions/blob/master/doc/…
  • @zerkms 我也尝试过,但没有运气。我看到了一些认为可行的地方。
  • @Jean 看起来需要 ORM?
  • 嗯,也许吧,我在 Symfony 项目中使用它,所以我有完整的 Doctrine 包

标签: mysql doctrine-orm


【解决方案1】:

一个较晚的答案,但我发现最简单的方法是首先运行查询以获取 NOW() 的值,然后插入该字符串。

一个例子:

$now = $db->fetchColumn("SELECT NOW()");
$db->insert('table', array(
    'field1' => $field1
    ,'created' => $now
));

如果您能够确保您的 PHP/MySQL 时间是同步的,一个稍微不太理想的替代方案是,您始终可以在 PHP 中创建 DateTime 对象并将其格式化为准备好用于 MySQL 的字符串:

$created = new \Datetime('now', new \DateTimeZone('Europe/Paris'));
$created->format('Y-m-d H:i:s')

【讨论】:

    【解决方案2】:

    insert 不是一个很好的选择。所以Expression mysql NOW() in Doctrine QueryBuilder 的答案表明手动知道该变量会发生什么。

    这需要最近发布的 DBAL >= 2.5。 2014 年你会倒霉。请注意,datetime 是一个有效字符串,但似乎没有常量 http://php.net/manual/en/pdo.constants.php

    public function insert($params) {
    
      if (!isset($params[static::CREATED_ON])) {
        $params[] = [static::CREATED_ON, new \Datetime('now'), 'datetime'];
      }
    
      if (!isset($params[static::MODIFIED_ON])) {
        $params[] = [static::MODIFIED_ON, new \Datetime('now'), 'datetime'];
      }
    
      $conn = $this->_dbs['write'];
      $query_builder = $conn->createQueryBuilder();
    
      $query_builder->insert(static::TABLE);
    
      foreach ( $params as $location => $data ) {
    
        $field = $data[0];
        $value = $data[1];
        $type = (isset($data[2])) ? $data[2] : \PDO::PARAM_STR;
        $prep = (isset($data[3])) ? $data[3] : '?';
    
        $query_builder
          ->setValue($field, $prep)
          ->setParameter($location, $value, $type);
    
      }
    
      $return = $query_builder->execute();
    
      if (!$return) {
        throw new \Exception("Failed to execute statement");
      }
    
      return $conn->lastInsertId();
    
    }
    

    public function update($params, $where) {
    
      $conn = $this->_dbs['write'];
      $query_builder = $conn->createQueryBuilder();
    
      $query_builder->update(static::TABLE);
    
      foreach ( $params as $location => $data ) {
        // can do arbitrary expressions via ['field', null, null, 'ANY EXPRESSION YOU WANT']
        // ie ['votes', null, null,'votes=votes+25']
        // or ['votes', '1', \PDO::PARAM_INT, 'votes + ?']
        $field = $data[0];
        $value = $data[1];
        $type = (isset($data[2])) ? $data[2] : \PDO::PARAM_STR;
        $prep = (isset($data[3])) ? $data[3] : '?';
    
        $query_builder
          ->set($field, $prep)
          ->setParameter($location, $value, $type);
    
      }
    
      $query_builder->where($where);
    
      return $query_builder->execute();
    
    }
    

    【讨论】:

      【解决方案3】:

      您似乎正在尝试完成 TIMESTAMP 列类型自动执行的操作。这已经存在了比 2014 年更长的时间。使用它,并停止尝试手动管理您的 created_onupdated_on 字段。 https://dev.mysql.com/doc/refman/5.1/en/datetime.html

      【讨论】:

      • 公平的答案,但对表达式更好奇 - 碰巧这种情况适用于 NOW()。另一方面,我不知道使用 DBAL 执行 COLUMN_NAME+1 的答案……现在我要看看我是否能做到。点赞=投票+1
      猜你喜欢
      • 2013-07-29
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      • 2015-05-07
      • 2012-12-04
      • 2012-01-23
      • 2015-03-12
      • 1970-01-01
      相关资源
      最近更新 更多