【问题标题】:Mysql PDO prepare statement issue with DATE data typeDATE 数据类型的 Mysql PDO 准备语句问题
【发布时间】:2012-08-24 11:37:50
【问题描述】:

日期数据类型有问题。 我有一个 php mysql pdo 语句:

$mystmt = $mydb->prepare("
    SELECT  `ad_id` 
        FROM `tbl_actions`
        WHERE 
            (`actiondate` > :nowcookietime  )
");
$mystmt->execute(array(
            ':nowcookietime'=>date("Y-m-d H:i:s", time()-$cookiedurationlock),
           )
);
$testnotinsql = $mystmt->fetch(PDO::FETCH_ASSOC); // EMPTY

代码运行返回空。但是,如果我从 general_log 获取下面的 sql 并在 sql 工具(HeidiSQL)中运行,它将返回记录。 来自 general_log 的 SQL:

SELECT  ad_id 
        FROM tbl_actions
        WHERE 
            (actiondate> '2012-08-24 17:53:21' ) 

我的 PHP 时区是 UTC+7 Mysql是SYSTEM(哪个UTC) 据我了解,如果使用相同的时区在 php 中插入和查询,则不是时区问题。

我用强制字符串测试绑定参数

':nowcookietime'=>date("Y-m-d H:i:s", time()-$cookiedurationlock),

但它同样是空的。

但是:如果使用引号,则返回行

':nowcookietime'=>"'".date("Y-m-d H:i:s", time()-$cookiedurationlock)."'",

你能澄清一下这句话有什么问题吗,因为我知道我们不需要报价,mysql pdo 报价给我们。

编辑 1:

我更新了正确的 sql。从测试中获取时,在 sql 中使用引号是我的错误。周围没有引号:nowcookietime 仍然为空。

关闭
请看下面我的回答。

【问题讨论】:

  • 试试这个 ':nowcookietime'=>"'".date("Y-m-d H:i:s", time()-$cookiedurationlock)."'"
  • 只需在准备好的语句中删除 :nowcookietime 周围的引号即可。 (actiondate > :nowcookietime ) 应该是这样,然后再次运行代码。
  • 它是正确的数据类型吗? php.net/manual/en/pdo.constants.php
  • @N.B 对不起我的错误。 sql在sql中没有引号,它取自我的测试。 sql中没有引号,它返回空。我更新了我的问题。
  • +1 提醒我有关 general_log,检查此日志有助于确定我的问题。

标签: php mysql sql pdo prepared-statement


【解决方案1】:

作为 N.B.在评论中说使用

(actiondate > :nowcookietime)

在 sql 语句中没有 :nowcookietime 周围的单引号。

独立示例:

<?php
$mydb = setup();
$cookiedurationlock = 40;
$mystmt = $mydb->prepare("
    SELECT  `ad_id` 
        FROM `tmp_tbl_actions`
        WHERE 
            (`actiondate` > :nowcookietime )
");
$mystmt->execute(array(
    ':nowcookietime'=>date("Y-m-d H:i:s", time()-$cookiedurationlock),
));
$testnotinsql = $mystmt->fetch(PDO::FETCH_ASSOC);
var_dump($testnotinsql);


function setup() {
    $pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'localonly', 'localonly');
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->exec('
        CREATE TEMPORARY TABLE tmp_tbl_actions (
            ad_id int auto_increment,
            actiondate DATETIME,
            primary key(ad_id),
            key(actiondate)
        )
    ');

    $stmt = $pdo->prepare('INSERT INTO tmp_tbl_actions (actiondate) VALUES(?)');
    $t = time();
    for($i=-80; $i<10; $i++) {
        $stmt->execute(array(date('Y-m-d H:i:s', $t+$i)));
    }
    return $pdo;
}

打印

array(1) {
  ["ad_id"]=>
  string(2) "42"
}

中的冒号
':nowcookietime'=>date(...

可能是多余的,但它也在示例 #2 中使用,http://docs.php.net/manual/en/pdostatement.execute.php

【讨论】:

  • 对不起我的错误。 sql在sql中没有引号,它取自我的测试。 sql中没有引号,它也返回空。我更新了我的问题。我将在设置和不设置时区的情况下测试您的脚本,看看会发生什么。谢谢
  • 您的代码运行正确,但我的代码仍然错误。我将把我的代码取出到单独的脚本中再次测试。
【解决方案2】:

我知道为什么。

  1. 基本上有脚本设置$cookiedurationlock 太短,所以大多数时候它是空的。
  2. 添加引号时,比较将是 (actiondate > '\'2012-08-25 02:28:22\'' ),因此它将返回行。
  3. 在查询之后,有一个插入新操作行。因此,当我从工具运行跟踪 sql 时,数据发生了变化,它返回了在此 sql 之后添加的新数据。

我想我必须将我的脚本组织成更简单的脚本。
谢谢大家的帮助。

【讨论】:

    猜你喜欢
    • 2011-07-13
    • 1970-01-01
    • 2011-06-02
    • 2011-06-21
    • 1970-01-01
    • 2019-08-04
    • 2016-09-10
    • 1970-01-01
    • 2017-09-19
    相关资源
    最近更新 更多