Uyarı: PDOStatement :: execute (): sqlstate [HY093]: Geçersiz parametre numarası: ilişkili değişkenleri sayısı belirteçleri sayısı eşleşmiyor

5 Cevap php

Ben PHP PDO ile çalışıyorum ve şu sorun var:

Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens in /var/www/site/classes/enterprise.php on line 63

İşte benim kod:

    public function getCompaniesByCity(City $city, $options = null) {
  $database = Connection::getConnection();

  if(empty($options)) {
   $statement = $database->prepare("SELECT * FROM `empresas` WHERE `empresas`.`cidades_codigo` = ?");
   $statement->bindValue(1, $city->getId());
  }
  else {
   $sql = "SELECT * FROM `empresas`
    INNER JOIN `prods_empresas` ON `prods_empresas`.`empresas_codigo` = `empresas`.`codigo` WHERE ";

   foreach($options as $option) {
    $sql .= '`prods_empresas`.`produtos_codigo` = ? OR ';
   }

   $sql = substr($sql, 0, -4);
   $sql .= ' AND `empresas`.`cidades_codigo` = ?';

   $statement = $database->prepare($sql);

   echo $sql;

   foreach($options as $i => $option) {
    $statement->bindValue($i + 1, $option->getId());
   }

   $statement->bindValue(count($options), $city->getId());
  }

  $statement->execute();

  $objects = $statement->fetchAll(PDO::FETCH_OBJ);
  $companies = array();

  if(!empty($objects)) {
   foreach($objects as $object) {
    $data = array(
     'id' => $object->codigo,
     'name' => $object->nome,
     'link' => $object->link,
     'email' => $object->email,
     'details' => $object->detalhes,
     'logo' => $object->logo
    );

    $enterprise = new Enterprise($data);
    array_push($companies, $enterprise);
   }

   return $companies;
  }
 }

5 Cevap

(?) Bu uzun bir dizi 'veya' karşılaştırmalar oluşturmak için çalışıyoruz gibi görünüyor: if (x=1) or (x=2) or (x=3) etc.... Bunu daha kolay değiştirin bulabilirsiniz:

$cnt = count($options);
if ($cnt > 0) {
   $placeholders = str_repeat(', ?', $cnt - 1);
   $sql .= 'WHERE '`prods_empresas`.`produtos_codigo` IN (?' . $placeholders . ')';
}

hangi 5 seçenek olsaydı, size verecek

 WHERE prods_empresas.produtos_condigo IN (?, ?, ?, ?, ?)

Ve sonra değerleri ile bağlama yapmak:

$pos = 1;
foreach ($options as $option) {
   $statement->bindValue($pos, $option->getId());
   $pos++
}

Sen ilişkili parametrelerin miktarı ve SQL bağlar miktarı arasında bir uyumsuzluk var. ? miktarı ve bağlı parametrelerin miktarının aynı olduğunu Çift kontrol edin.

Varolmayan bir parametre bağlama çalıştı varsa Ayrıca, HY093 görünecektir:

$stmt = "INSERT INTO table VALUES (:some_value)";
$stmt->bindValue(':someValue', $someValue, PDO::PARAM_STR);

:some_value eşleşmiyor görüyoruz :someValue! Düzeltme:

$stmt = "INSERT INTO table VALUES (:some_value)";
$stmt->bindValue(':some_value', $someValue, PDO::PARAM_STR);

SQL konumsal parametreler 1'den başlar. Size $ seçenekler döngüde pozisyona $i+1 bağlanarak hallediyoruz.

Ama o zaman cidades_codigo $ seçenekler döngüsünde belirlenen son parametre yazar ki, count($options) konumlandırmak için son parametre bağlama.

Sen konumlandırmak için son parametre bağlamak gerekiyor count($options)+1.


FWIW, hiç bindValue() gerekmez. Bu sadece execute() parametrelerin bir dizi geçmek kolay. İşte bu fonksiyon yazmak istiyorum nasıl:

public function getCompaniesByCity(City $city, $options = null) {
  $database = Connection::getConnection();

  $sql = "SELECT * FROM `empresas` WHERE `empresas`.`cidades_codigo` = ?"

  $params = array();
  $params[] = $city->getId();

  if ($options) {
    $sql .= " AND `prods_empresas`.`produtos_codigo` IN (" 
      . join(",", array_fill(1, count($options), "?") . ")";
    foreach ((array)$options as $option) {
      $params[] = $option->getId();
    }
  }

  $statement = $database->prepare($sql);

  echo $sql;

  $statement->execute($params);
  . . .

Ayrıca prepare() ve orada bir hata var, ve bu kontrol ve rapor gerekiyorsa execute(), bu false olacak dönüş değerini kontrol ediniz hatası. Yoksa hata istisnalar atmak PDO'yu etkinleştirin.

Ben nedeniyle PDO geçirilen adlandırılmış parametre haritalama dizideki ekstra girdileri olan bu sorunun içine koşuyordu :: Bildirimi-> execute ()

$args=array (":x" => 17 );
$pdo->prepare("insert into foo (x) values (:x)");
$pdo->execute($args); // success
$args[':irrelevant']=23;
$pdo->execute($args) // throws exception with HY093

Eğer döngü içinde $i+1 yaptık beri çok count($options) eşit olacaktır son $i+1 hangi bir yinelenen binding.Try yapar

 foreach($options as $i => $option)
 { 
      $statement->bindValue($i + 1, $option->getId()); 
 }

 $statement->bindValue(count($options)+1, $city->getId());