SQLSTATE[HY093]:参数号无效:参数未定义
Posted
技术标签:
【中文标题】SQLSTATE[HY093]:参数号无效:参数未定义【英文标题】:SQLSTATE[HY093]: Invalid parameter number: parameter was not defined 【发布时间】:2012-06-13 12:58:08 【问题描述】:// 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);
上面的代码失败并出现以下错误
虽然在执行之前调用count($matches) == count($values)
?
这是怎么回事?
【问题讨论】:
您是否尝试过传递 array_values($matches)? 为什么是ON DUPLICATE KEY UPDATE hash = hash
?也可以INSERT IGNORE ...
。你的意思是UPDATE hash = VALUES(hash)
?
$values
数组在循环之前是否已经包含某些内容?另外,为什么不准备一个INSERT INTO hashes (hash) VALUES (?)
并多次执行呢?
@eggyal 我正在插入大约 1000 个值,并且多次插入的速度大约快 10 倍 :)
@Griff:在多次执行准备好的语句的情况下是否也是如此?我自己从未对其进行基准测试,但一直认为性能影响可以忽略不计......
【参考方案1】:
如果您在 php 中的列名与数据库列名不匹配,我发现的相同错误将显示,请仔细检查。这就是我错了。
【讨论】:
【参考方案2】:我在绑定时使用了错误的参数名后出现了同样的错误。
注意:tokenHash在查询的VALUES
子句中,但: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】:您收到此错误:
SQLSTATE[HY093]:参数号无效:参数未定义
是因为$values
和$matches
中的元素个数不一样或者$matches
包含的元素多于1个。
如果$matches
包含多于1 个元素,则插入将失败,因为查询中只引用了1 个列名(hash
)
如果 $values
和 $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。
【讨论】:
很好的答案,我刚刚遇到了这个问题,因为我定义了两个具有相同标识符的列 -:example
,这也应该是一个检查点!
只是添加,可能是因为您尝试绑定的参数根本不存在...
@Darren - 你是我的救命恩人。在我在 foreach 循环中执行的 bindParam 调用中,我忘记包含来自数组索引的键,所以我得到了 bindParam(':id', 'someValue'), bindParam(':id', 'someValue2'),.. . 而不是 bindParam(':id0', 'someValue'), bindParam(':id1', 'someValue'),... 希望这可以帮助某人解决他的谜团
我认为您误解了 OP 的意图。他内爆了$count
次(?)
- 而不仅仅是?
- 和,
因为像INSERT INTO hashes(hash) VALUES('What'),('Terrible'),('Failure');
这样的东西可以在SQL 中工作,在一个语句中插入3 行。您的回答建议类似INSERT INTO hashes(hash) VALUES('What', 'Terrible' , 'Failure');
- 引用一列并为一行提供3个值!那会抛出 Column count doesn't match value count
错误-这怎么能得到 +45 的赞成票和 OP 的批准?(当然:“你需要稍微调整一下。”你说...)【参考方案4】:
我知道答案很有用,但是由于某种原因它对我不起作用,但是我已经使用以下代码改变了情况,它是完美的
<?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
?>
【讨论】:
【参考方案5】:SQLSTATE[HY093]:参数号无效:参数未定义
很遗憾,此错误无法描述与同一问题相关的一系列不同问题 - 绑定错误。它也没有指定错误在哪里,所以你的问题不一定在执行,而是已经“准备好”的sql语句。
这些是可能的错误及其解决方案:
存在参数不匹配 - 字段数与已绑定的参数不匹配。注意数组中的数组。仔细检查 - 使用 var_dump($var)。 "print_r" 不一定会显示数组中的索引是否是另一个数组(如果数组中有一个值),而 var_dump 会。
您尝试使用相同的绑定值进行绑定,例如:“:hash”和“:hash”。每个索引都必须是唯一的,即使在逻辑上对两个不同的部分使用相同的索引是有意义的,即使它是相同的值。 (类似于常量但更像占位符)
如果您在一个语句中绑定多个值(“INSERT”通常是这种情况),您需要先绑定参数,然后再绑定值到参数。这里的过程是将参数绑定到字段,然后将值绑定到参数。
// 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 时,您可以使用 `` 但它不是必需的,但请确保保持一致。
'' 单引号中的任何值始终被视为字符串,不会被读取为要绑定到的列/表名称或占位符。
【讨论】:
感谢您提出理由 #2,直到我在这里找到这个,我才惊呆了。以上是关于SQLSTATE[HY093]:参数号无效:参数未定义的主要内容,如果未能解决你的问题,请参考以下文章
致命错误:未捕获PDOException:SQLSTATE [HY093]:参数号无效:无参数
PHP PDOException:“SQLSTATE [HY093]:无效参数号”
SQLSTATE[HY093]:无效的参数号 - PDO Select 语句
SQLSTATE[HY093]:参数号和 PDO::ATTR_EMULATE_PREPARES 无效