【问题标题】:PDO Query Not Inserting - HY093 error message but correct number of bound variablesPDO 查询未插入 - HY093 错误消息但绑定变量的数量正确
【发布时间】:2015-10-07 13:12:59
【问题描述】:

代码

$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中执行时却没有?

【问题讨论】:

  • 您已准备好收到警告 - 您现在有 error_reporting(E_ALL);display_errors 吗?我很好奇errorInfo() 是否真的在之前 execute() 被填充,在尝试prepare() 以知道语句是否首先成功准备之后。在prepare() 之后检查errorInfo()(或暂时打开ERRMODE_EXCEPTION,因此如果失败,代码永远不会超过prepare()
  • @MichaelBerkowski 打开提供的 PHP 错误:PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined 指向 execute() 函数。目前还不清楚哪个参数没有被绑定,因为它在 phpMyAdmin 中工作正常,我找不到任何未绑定的参数?
  • 如果我记得,当使用 ? 占位符而不是命名占位符时,PDO 会自行丢弃 execute() 中的数组键,但如果不是这种情况,您也应该尝试execute(array_values($fullStmt)) 在绑定之前摆脱关联键。
  • 那行得通 - 将其设置为答案,我会接受。干杯!
  • 是的,我也刚刚对其进行了测试以发现这是 PDO 的行为。答案即将到来。

标签: php mysql pdo


【解决方案1】:

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

因此,您需要消除 PDO 的数组键,以便正确地将数组值与其位置占位符绑定。这很容易通过在数组上调用array_values() 来完成,因为它被传递给execute()

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

请注意,PDO 对数组顺序的正确解释取决于其值的开始顺序是否完全正确。您的 $fullStmt 数组确实以正确的顺序排列,无论您以何种方式生成它。但是,如果该过程发生变化,则删除数组键可能会导致您的 INSERT 语句将值放入错误的列中。重构语句生成以在 VALUES () 列表中使用命名参数(如 :competition_code)并继续使用关联数组来防止这个潜在的触发点可能是值得的。

【讨论】:

  • 实际上,如果此数组的顺序发生变化,即您在 HTML 中移动一个字段,您可能会尝试将数据放在错误的列中。我建议动态构建列列表以及数据列表,这样以后就不会被你发现了。
  • @RiggsFolly 我同意这个评价。我会为此添加一个注释。
  • @RiggsFolly 在这种情况下,数据是从其他几个数组动态创建的——它们将始终按此顺序排列,无论值是填充的、空的还是 NULL,但你提出了一个很好的观点。
  • @BenPearlKahan 他们将永远按照这个顺序 著名的溺水者遗言。 泰坦尼克号是永不沉没的 什么是有人负责修改代码??
  • @BenPearlKahan 不咄咄逼人,只是试图传递多年被假设绊倒的经验。随着时间的推移,在改变之前的几天/几个月/几年,即 bin 那里,做出不正确的假设,付出了代价.双脚中弹,不止一次。
猜你喜欢
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多