2010-04-26 43 views
6

Tôi đang làm việc với PHP PDO và tôi có vấn đề sau đây:Cảnh báo: PDOStatement :: thực hiện(): SQLSTATE [HY093]: số tham số không hợp lệ: số biến ràng buộc không phù hợp với số lượng thẻ trong

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 

đây là mã của tôi:

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; 
    } 
} 

Trả lời

-2

vì bạn đã đăng $i+1 trong vòng lặp để count($options) sẽ bằng cuối cùng $i+1 mà làm cho một binding.Try trùng lặp

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

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

Dường như bạn đang cố gắng tạo một chuỗi dài (?) Của 'hoặc' so sánh: if (x=1) or (x=2) or (x=3) etc.... Bạn có thể tìm thấy nó dễ dàng hơn để thay thế nó bằng:

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

đó, nếu có 5 tùy chọn, sẽ cung cấp cho bạn

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

Và sau đó làm các giá trị ràng buộc với:

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

Bạn có một sự không phù hợp giữa số lượng các tham số ràng buộc và số lượng các ràng buộc trong SQL. Kiểm tra kỹ xem số lượng ? và số lượng thông số bị ràng buộc là như nhau hay không.

Bên cạnh đó, HY093 sẽ hiển thị nếu bạn đã cố gắng để ràng buộc một tham số không tồn tại:

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

Thấy rằng :some_value không phù hợp :someValue! Sửa chữa là:

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

Thông số vị trí trong SQL bắt đầu lúc 1. Bạn đang xử lý việc này bằng cách liên kết với vị trí $i+1 trong vòng tùy chọn $.

Nhưng sau đó bạn ràng buộc tham số cuối cùng cho cidades_codigo đến vị trí count($options), ghi đè tham số cuối cùng được đặt trong vòng tùy chọn $.

Bạn cần phải liên kết thông số cuối cùng với vị trí count($options)+1.


FWIW, bạn không cần phải bindValue() chút nào. Việc chuyển một mảng tham số đến execute() dễ dàng hơn. Đây là cách tôi muốn viết chức năng này:

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); 
    . . . 

Ngoài ra hãy chắc chắn để kiểm tra giá trị trả về của prepare()execute(), nó sẽ được false nếu có một lỗi, và bạn cần phải kiểm tra cho rằng, báo cáo lỗi. Hoặc cho phép PDO ném ngoại lệ về lỗi.

0

tôi đã chạy vào vấn đề này do có các mục bổ sung trong mảng lập bản đồ tham số có tên truyền cho PDO :: Câu lệnh> thực hiện()

$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 
+0

Tôi không hiểu nếu điều này là một câu trả lời hay chỉ là một bình luận về OP.Bạn có thể nói lại được không? – paqogomez

Các vấn đề liên quan