41
// BUILD VALUES
$count = count($matches);
for($i = 0; $i < $count; ++$i) {
    $values[] = '(?)';
}
// INSERT INTO DATABASE
$q = $this->dbc->prepare("INSERT INTO hashes (hash) VALUES " . implode(', ', $values) . " ON DUPLICATE KEY UPDATE hash = hash");
$q->execute($matches);

上面的代码失败并出现以下错误

SQLSTATE[HY093]:参数号无效:参数未定义

虽然count($matches) == count($values)在执行之前什么时候被调用?

这里发生了什么?

4

5 回答 5

53

您收到的此错误:

SQLSTATE[HY093]:参数号无效:参数未定义

是因为$values&中的元素个数$matches不一样或者$matches包含的元素多于1个。

如果$matches包含超过 1 个元素,则插入将失败,因为在 query( hash)中只引用了 1 个列名

如果$values&$matches不包含相同数量的元素,则插入也将失败,因为查询需要 x 参数但它正在接收 y 数据$matches

我相信您还需要确保列哈希也具有唯一索引。

试试这里的代码:

<?php

/*** mysql hostname ***/
$hostname = 'localhost';

/*** mysql username ***/
$username = 'root';

/*** mysql password ***/
$password = '';

try {
    $dbh = new PDO("mysql:host=$hostname;dbname=test", $username, $password);
    /*** echo a message saying we have connected ***/
    echo 'Connected to database';
    }
catch(PDOException $e)
    {
    echo $e->getMessage();
    }

  
$matches = array('1');
$count = count($matches);
for($i = 0; $i < $count; ++$i) {
    $values[] = '?';
}

// INSERT INTO DATABASE
$sql = "INSERT INTO hashes (hash) VALUES (" . implode(', ', $values) . ") ON DUPLICATE KEY UPDATE hash='hash'";
$stmt = $dbh->prepare($sql);
$data = $stmt->execute($matches);

//Error reporting if something went wrong...
var_dump($dbh->errorInfo());

?>

你需要稍微调整一下。

我使用的表结构在这里

CREATE TABLE IF NOT EXISTS `hashes` (
  `hashid` int(11) NOT NULL AUTO_INCREMENT,
  `hash` varchar(250) NOT NULL,
  PRIMARY KEY (`hashid`),
  UNIQUE KEY `hash1` (`hash`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

代码在我的 XAMPP 服务器上运行,该服务器使用 PHP 5.3.8 和 MySQL 5.5.16。

于 2012-06-10T10:03:58.703 回答
8

SQLSTATE[HY093]:参数号无效:参数未定义

不幸的是,此错误不能描述与同一问题相关的一系列不同问题 - 绑定错误。它也没有指定错误在哪里,因此您的问题不一定在执行中,而是已经“准备好”的 sql 语句。

这些是可能的错误及其解决方案:

  1. 存在参数不匹配 - 字段数与已绑定的参数不匹配。注意数组中的数组。仔细检查 - 使用var_dump($var)。“ print_r ”不一定会显示数组中的索引是否是另一个数组(如果数组中有一个值),而var_dump会。

  2. 您尝试使用相同的绑定值进行绑定,例如:“:hash”和“:hash”。每个索引都必须是唯一的,即使在逻辑上对两个不同的部分使用相同的索引是有意义的,即使它是相同的值。(它类似于一个常量,但更像一个占位符)

  3. 如果您在一个语句中绑定了多个值(通常是使用“INSERT”的情况),您需要先绑定参数,然后再绑定值到参数。这里的过程是将参数绑定到字段,然后将值绑定到参数。

    // Code snippet
    $column_names = array();
    $stmt->bindParam(':'.$i, $column_names[$i], $param_type);
    $stmt->bindValue(':'.$i, $values[$i], $param_type);
    $i++;
    //.....
    
  4. 将值绑定到 column_names 或 table_names 时,您可以使用 `` 但它不是必需的,但请确保保持一致。

  5. '' 单引号中的任何值始终被视为字符串,不会被读取为要绑定的列/表名称或占位符。

于 2018-02-12T17:05:38.933 回答
3

绑定时使用错误的参数名称后,我遇到了同样的错误。

注意:tokenHashVALUES查询的子句中,但:token_hash在绑定时。

修复一个或另一个解决了错误。

// Prepare DB connection
$sql = 'INSERT INTO rememberedlogins (token_hash,user_id,expires_at)
        VALUES (:tokenHash,:user_id,:expires_at)';
$db = static::getDB();
$stmt = $db->prepare($sql);

// Bind values
$stmt->bindValue(':token_hash',$hashed_token,PDO::PARAM_STR);
于 2020-06-07T00:53:19.670 回答
0

如果您在 PHP 中的列名与数据库列名不匹配,我发现的相同错误将显示,请仔细检查。这就是我错了。

于 2021-11-16T19:50:13.900 回答
-2

我知道答案很有用但是由于某种原因它对我不起作用但是我已经使用以下代码改变了情况并且它是完美的

    <?php

$codigoarticulo = $_POST['codigoarticulo'];
$nombrearticulo = $_POST['nombrearticulo'];
$seccion        = $_POST['seccion'];
$precio         = $_POST['precio'];
$fecha          = $_POST['fecha'];
$importado      = $_POST['importado'];
$paisdeorigen   = $_POST['paisdeorigen'];
try {

  $server = 'mysql: host=localhost; dbname=usuarios';
  $user   = 'root';
  $pass   = '';
  $base   = new PDO($server, $user, $pass);

  $base->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  $base->query("SET character_set_results = 'utf8',
                     character_set_client = 'utf8',
                     character_set_connection = 'utf8',
                     character_set_database = 'utf8',
                     character_set_server = 'utf8'");

  $base->exec("SET character_set_results = 'utf8',
                     character_set_client = 'utf8',
                     character_set_connection = 'utf8',
                     character_set_database = 'utf8',
                     character_set_server = 'utf8'");

  $sql = "
  INSERT INTO productos
  (CÓDIGOARTÍCULO, NOMBREARTÍCULO, SECCIÓN, PRECIO, FECHA, IMPORTADO, PAÍSDEORIGEN)
  VALUES
  (:c_art, :n_art, :sec, :pre, :fecha_art, :import, :p_orig)";
// SE ejecuta la consulta ben prepare
  $result = $base->prepare($sql);
//  se pasan por parametros aqui
  $result->bindParam(':c_art', $codigoarticulo);
  $result->bindParam(':n_art', $nombrearticulo);
  $result->bindParam(':sec', $seccion);
  $result->bindParam(':pre', $precio);
  $result->bindParam(':fecha_art', $fecha);
  $result->bindParam(':import', $importado);
  $result->bindParam(':p_orig', $paisdeorigen);
  $result->execute();
  echo 'Articulo agregado';
} catch (Exception $e) {

  echo 'Error';
  echo $e->getMessage();
} finally {

}

?>
于 2019-12-14T22:44:41.117 回答