// 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]:参数号无效:参数未定义
虽然在调用execute之前调用count($matches) == count($values)
?
这里发生了什么?
答案 0 :(得分:43)
您收到此错误:
SQLSTATE [HY093]:参数号无效:参数未定义
是因为$values
&amp;中的元素数量$matches
不相同或$matches
包含多于1个元素。
如果$matches
包含多于1个元素,则插入将失败,因为查询中只引用了1个列名(hash
)
如果$values
&amp; $matches
不包含相同数量的元素,因此插入也会失败,因为查询需要x参数但是它正在接收y数据$matches
。
我相信你还需要确保列散列上也有唯一的索引。
尝试代码here:
<?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());
?>
您需要稍微调整一下。
我使用的表格结构是here:
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。
我希望这会有所帮助。
答案 1 :(得分:4)
SQLSTATE [HY093]:参数号无效:参数未定义
不幸的是,此错误不能描述与同一问题相关的一系列不同问题 - 绑定错误。它也没有指定错误的位置,因此您的问题不一定在执行中,而是已经准备好的sql语句&#39;。
这些是可能的错误及其解决方案:
参数不匹配 - 字段数与已绑定的参数不匹配。注意阵列中的数组。要仔细检查 - 使用 var_dump($ var)。 &#34; 的print_r &#34;并不一定会告诉你数组中的索引是否是另一个数组(如果数组中有一个值),而 var_dump 则会。
您尝试使用相同的绑定值进行绑定,例如:&#34;:hash&#34;和&#34;:哈希&#34;。每个索引都必须是唯一的,即使逻辑上对两个不同的部分使用相同也是有意义的,即使它是相同的值。 (它类似于常数,但更像是占位符)
如果您在语句中绑定了多个值(通常是&#34; INSERT&#34;的情况),则需要bindParam然后将bindValue绑定到参数。此处的过程是将参数绑定到字段,然后将值绑定到参数。
// Code snippet
$column_names = array();
$stmt->bindParam(':'.$i, $column_names[$i], $param_type);
$stmt->bindValue(':'.$i, $values[$i], $param_type);
$i++;
//.....
将值绑定到column_names或table_names时,您可以使用``但不是必需的,但请确保一致。
&#39;&#39;中的任何值单引号始终被视为字符串,不会被读取为要绑定的列/表名或占位符。
答案 2 :(得分:2)
我有同样的错误。我的问题是绑定时使用了错误的参数名称。
在查询中注意:tokenHash ,但在绑定时: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);
答案 3 :(得分:0)
我知道答案是有用的,但是由于某些原因它对我不起作用,但是我通过以下代码移动了这种情况,它是完美的
<?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 {
}
?>