PDO查询未插入 - HY093错误消息但正确的绑定变量数

时间:2015-10-07 13:13:00

标签: php mysql pdo

代码

$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$stmt = $dbh->prepare($query);
print_r($fullStmt);

if(!$stmt->execute($fullStmt))
{
    print_r($stmt->errorInfo());
    $full_query = "INSERT INTO `fixtures` (competition_code,competition_id,competition_name,season_id,season_name,
    timestamp,uid,last_modified,matchday,period,matchwinner,date,team1,team1_halfscore,team1_score,team1_goals,
    team1_side,team2,team2_halfscore,team2_score,team2_goals,team2_side) VALUES (";
    foreach($fullStmt as $val){ $full_query.= "'$val', "; }
    $full_query = trim($full_query, ", ");
    $full_query.= ");";
    exit($full_query);
}

输出

Array
(
    [competition_code] => EN_PR
    [competition_id] => 8
    [competition_name] => English Barclays Premier League
    [season_id] => 2013
    [season_name] => Season 2013/2014
    [timestamp] => 2013-10-30 09-03-49
    [uid] => g695281
    [last_modified] => 2013-10-15T12:35:58+00:00
    [matchday] => 1
    [period] => FullTime
    [matchwinner] => t7
    [date] => 2013-08-17 15:00:00 BST
    [team1] => t3
    [team1_halfscore] => 1
    [team1_score] => 1
    [team1_goals] => p44346/#/Goal
    [team1_side] => Home
    [team2] => t7
    [team2_halfscore] => 1
    [team2_score] => 3
    [team2_goals] => p54861/#/Goal//p83564/#/Goal//p54861/#/Penalty
    [team2_side] => Away
)
Array
(
    [0] => HY093
    [1] => 
    [2] => 
)
INSERT INTO `fixtures` (competition_code,competition_id,competition_name,season_id,season_name,
            timestamp,uid,last_modified,matchday,period,matchwinner,date,team1,team1_halfscore,team1_score,team1_goals,
            team1_side,team2,team2_halfscore,team2_score,team2_goals,team2_side) VALUES ('EN_PR', '8', 'English Barclays Premier League', '2013', 'Season 2013/2014', '2013-10-30 09-03-49', 'g695281', '2013-10-15T12:35:58+00:00', '1', 'FullTime', 't7', '2013-08-17 15:00:00 BST', 't3', '1', '1', 'p44346/#/Goal', 'Home', 't7', '1', '3', 'p54861/#/Goal//p83564/#/Goal//p54861/#/Penalty', 'Away');

概述

$fullStmt是一个值数组,我有一个查询如下:

$query = "INSERT INTO `fixtures` (
                competition_code,
                competition_id,
                competition_name,
                season_id,
                season_name,
                timestamp,
                uid,
                last_modified,
                matchday,
                period,
                matchwinner,
                date,
                team1,
                team1_halfscore,
                team1_score,
                team1_goals,
                team1_side,
                team2,
                team2_halfscore,
                team2_score,
                team2_goals,
                team2_side
                ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

但是,在尝试执行时,它会返回FALSE。我输出结果查询,当直接将其插入 phpMyAdmin 时,它会成功插入。

为什么在phpMyAdmin的SQL字段中运行代码时却没有问题,但在PHP中执行时却没有?

1 个答案:

答案 0 :(得分:4)

在我自己测试之前,我不确定PDO中的这种行为,但由于$fullStmt中的值数组是关联数组,因此PDO实际上是在尝试根据数组键绑定命名参数。您最初准备的语句使用位置?占位符,因此命名参数不存在(并且不能与?混合使用)。

因此,您需要消除PDO的数组键,以正确地将数组值与其位置占位符绑定。最简单的方法是在数组传递给execute()时调用array_values()

// Strip off the associative array keys...
if(!$stmt->execute(array_values($fullStmt))) {
   // etc
}

请注意,PDO对数组顺序的正确解释取决于它的值是否正好以正确的顺序开始。您的$fullStmt数组确实按照您生成它的方式正确排列。但是,如果该进程发生更改,则剥离数组键可能会导致INSERT语句将值放入错误的列中。重构语句生成以在:competition_code列表中使用VALUES ()之类的命名参数并继续使用关联数组来防止这种潜在的跳闸点可能是值得的。