web-dev-qa-db-ja.com

SQLSTATE [HY093]:無効なパラメーター番号:パラメーターが定義されていません

_// 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)が呼び出されるのはいつですか?

ここで何が起こっていますか?

29
Griff

あなたが受け取っているこのエラー:

SQLSTATE [HY093]:無効なパラメーター番号:パラメーターが定義されていません

$values$matchesの要素数が同じでないか、$matchesに複数の要素が含まれているためです。

$matchesに複数の要素が含まれている場合、クエリで参照される列名は1つだけなので、挿入は失敗します(hash

$values$matchesに同じ数の要素が含まれていない場合、クエリはx paramsを予期しているが、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 ;

PHP 5.3.8 with MySQL 5.5.16を使用しているXAMPPサーバーでコードが実行されました。

これがお役に立てば幸いです。

45
Haroon

SQLSTATE [HY093]:無効なパラメーター番号:パラメーターが定義されていませんでした

残念ながら、このエラーは、同じ問題に関連するさまざまな問題、つまりバインディングエラーを説明するものではありません。また、エラーの場所は特定されないため、問題は必ずしも実行にあるとは限りませんが、すでに「準備された」SQLステートメントです。

考えられるエラーとその解決策は次のとおりです。

  1. パラメーターの不一致があります-フィールドの数がバインドされているパラメーターと一致しません。配列内の配列に注意してください。再確認するには-var_dump($ var)を使用します。 「print_r」は、配列内のインデックスが別の配列である場合(配列に値が1つある場合)は必ずしも表示されませんが、var_dumpになります。

  2. 同じバインド値を使用してバインドしようとしました。たとえば、「:hash」と「:hash」です。同じ値であっても、2つの異なる部分に同じものを使用することが論理的に意味がある場合でも、すべてのインデックスは一意である必要があります。 (定数に似ていますが、プレースホルダーに似ています)

  3. ステートメントで複数の値をバインドする場合(「INSERT」の場合によくあることです)、bindParamを実行してから、パラメーターにbindValueを実行する必要があります。ここでのプロセスは、パラメーターをフィールドにバインドしてから、値をパラメーターにバインドすることです。

    // 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. ''単一引用符内の値は常に文字列として扱われ、バインドする列/テーブル名またはプレースホルダーとして読み取られることはありません。

5
Danny F