PHP PDOException:“SQLSTATE [HY093]:无效参数号”

Posted

技术标签:

【中文标题】PHP PDOException:“SQLSTATE [HY093]:无效参数号”【英文标题】:PHP PDOException: "SQLSTATE[HY093]: Invalid parameter number" 【发布时间】:2013-08-04 10:06:48 【问题描述】:

我在尝试运行以下函数时收到错误“SQLSTATE[HY093]: Invalid parameter number”:

function add_persist($db, $user_id) 
    $hash = md5("per11".$user_id."sist11".time());
    $future = time()+(60*60*24*14);
    $sql = "INSERT INTO persist (user_id, hash, expire) VALUES (:user_id, :hash, :expire) ON DUPLICATE KEY UPDATE hash=:hash";
    $stm = $db->prepare($sql);
    $stm->execute(array(":user_id" => $user_id, ":hash" => $hash, ":expire" => $future));
    return $hash;

我觉得这很简单,我只是没听懂。有什么想法吗?

【问题讨论】:

You cannot use a named parameter marker of the same name twice in a prepared statement. http://php.net/manual/en/pdo.prepare.php 我知道该帖子的答案也可以回答我的问题,但我的问题绝对不可能重复。 在另一个问题中,fetchAll() 没有返回任何内容,因为查询与您的一样失败。其他作者只是没有注意到它。这本质上是同一个问题,因此值得将这两者联系起来。 是的,它们之间的联系是因为答案是相同的,但根据问题无法知道 【参考方案1】:

试试:

$sql = "INSERT INTO persist (user_id, hash, expire)
        VALUES (:user_id, :hash, :expire)
        ON DUPLICATE KEY UPDATE hash=:hash2";

$stm->execute(
    array(":user_id" => $user_id, 
          ":hash" => $hash, 
          ":expire" => $future,
          ":hash2" => $hash)
);

文档摘录 (http://php.net/manual/en/pdo.prepare.php):

当您调用 PDOStatement::execute() 时,您必须为希望传递给语句的每个值包含一个唯一的参数标记。您不能在准备好的语句中两次使用同名的命名参数标记。您不能将多个值绑定到单个命名参数,例如 SQL 语句的 IN() 子句。

【讨论】:

成功了!只要堆栈允许我,我就会接受你的回答。为什么原来的方法不起作用? @VijayRamamurthy,请仔细阅读:php.net/manual/en/pdo.prepare.php 你的回答和OP的问题有什么区别?【参考方案2】:

我知道这是一个老问题,但我认为值得注意的是,更合适的解决方案是通过适当地利用 SQL 来避免 PHP 中笨拙的解决方法:

INSERT INTO `persist` (`user_id`, `hash`, `expire`)
VALUES (:user_id, :hash, :expire)
ON DUPLICATE KEY UPDATE `hash`=VALUES(`hash`)

这样,你只需要发送一次值。

【讨论】:

【参考方案3】:
$stmt = $con->prepare("INSERT INTO items(Name, Description, Price, Country_Made, Status, Add_Date)  VALUES( :zname, :zdesc, :zprice, :zcountry, zstatus, now())");

$stmt-> execute(array(
   "zname" => $name,
   "zdesc" => $desc,
   "zprice" => $price,
   "zcountry" => $country,
   "zstatus" => $status 
));

【讨论】:

虽然这段代码可能有助于解决问题,但它并没有解释为什么和/或如何回答问题。提供这种额外的背景将显着提高其长期教育价值。请edit您的答案添加解释,包括适用的限制和假设。【参考方案4】:

这是使用 PDO 的一个限制。 PDO 只是确认查询和执行中的参数数量,并在任何不匹配时引发错误。如果您需要在查询中使用参数重复,则必须使用解决方法来解决它

$sql = "insert into persist(user_id, hash, expire) values
    (:user_id, :hash, :value) on duplicate key update
    hash = :hash2";
$stm->execute(array(':user_id' => $user_id, ':hash' => $hash, ':hash2' => $hash,
    ':expire' => $expire));

您可以参考这个以获得更详细的解决方法 - https://***.com/a/7604080/1957346

【讨论】:

太棒了!我花了两天时间调试除了一个特定查询之外的所有其他代码。答案是(正如上面的“vijrox”在评论中提到的那样)您不能在 PDO 中重用相同的命名参数。我有UPDATE users SET username = :username, caption = :caption WHERE username = :username,它不起作用,因为:username 出现了两次。解决方法是重命名第二个,最后是:UPDATE users SET username = :username, caption = :caption WHERE username = :user(最后一个 :user 不同)。

以上是关于PHP PDOException:“SQLSTATE [HY093]:无效参数号”的主要内容,如果未能解决你的问题,请参考以下文章

php - PDOException 找不到驱动程序 [重复]

Laravel 5.1 - `php artisan migrate` 给出了 'PDOException'

php artisan migrate:[PDOException] 找不到驱动程序

PHP PDOException没有捕获

php artisan migrate 抛出 PDOException

致命错误:第 19 行的 C:\xampp\htdocs\register.php 中抛出未捕获的异常“PDOException”