2012-07-20 36 views
9

Ive đã theo dõi một loạt các ví dụ khác nhau về việc sử dụng SELECT trong câu lệnh đã chuẩn bị, nhưng không có gì được trả lại. EDIT Tôi đã thay đổi mã của tôi một chút để trông như thế này:Gặp sự cố khi thực hiện truy vấn SELECT trong câu lệnh đã chuẩn bị

$date1 = 2012-01-01; 
$date2 = 2012-01-31; 
$sql_con = new mysqli('db', 'username', 'password', 'database'); 

if($stmt = $sql_con->prepare("SELECT eventLogID FROM Country WHERE countryCode=? AND date BETWEEN ? AND ?")){ 

    $stmt->bind_param("sss", $country_code, $date1,$date2); 

    $stmt->execute(); 

    $i=0; 
    while ($stmt->fetch()){ 
    $stmt->bind_result($row[$i]); 
    $i++; 
    } 

    $stmt->close(); 
$sql_con->close(); 

Bây giờ tất cả các mục mong muốn, ngoại trừ người đầu tiên, được thêm vào $ row []. Tại sao không nhập mục đầu tiên? Cảm ơn bạn trước!

+0

Bạn sử dụng * trong truy vấn của bạn , nhưng $ hàng trong bind_result của bạn ($ row). bind_result nên chứa các cột mà tôi nghĩ. Đọc thêm tại đây: http://nl3.php.net/manual/en/mysqli-stmt.bind-result.php Vì vậy, biến hàng $ của bạn chứa cột đầu tiên của bất cứ điều gì nó * có nghĩa là. (Tránh * trong tất cả các truy vấn của bạn, nhưng đó là một vấn đề khác.) –

Trả lời

17

EDIT 07/2015 (câu hỏi đã được chỉnh sửa từ câu trả lời ban đầu nhưng nguyên tắc cơ bản đều giống nhau)

NeverSELECT * trong một môi trường sản xuất, nó sẽ chỉ trở lại cắn bạn trong kỳ lạ, không thể đoán trước và dường như không liên quan. Bằng cách chỉ định các cột bạn muốn, bạn sẽ đảm bảo rằng thứ tự cột, kiểu dữ liệu, ràng buộc và tất cả các loại phần tử khác sẽ không gây ra sự cố cho bạn trong thời gian dài.

Câu trả lời này vẫn chủ yếu hợp lệ vì vậy tôi sẽ để nguyên ở đây, nhưng việc lấy đi chính là: sử dụng PDO, 98% trong số những thứ bạn cần với nhiều hơn và nhiều hơn nữa API ngắn gọn trên cùng một kết thúc. Nếu bạn cần một API RDBMS cụ thể phức tạp hơn thì bạn đã hiểu được những vấn đề bạn có và tại sao bạn cần mysqli etc thay thế.


SELECT * không hoạt động tốt với các câu lệnh chuẩn bị MySQL. Đó là một trong những lý do chính tôi khuyên bạn nên thay thế PDO - đó và yêu cầu vô lý để ràng buộc tham chiếu biến thay vì giá trị cho các tham số.

$stmt->bind_result($row); 

này không được ràng buộc kết quả hàng cho một biến, nó sẽ chỉ được ràng buộc một cột duy nhất. Và bởi vì bạn đã sử dụng SELECT *, nó không làm những gì bạn muốn nó.

Nếu bạn muốn sử dụng MySQLi trên PDO (như tôi muốn giới thiệu), có một vài ví dụ hay về cách SELECT * trong các ý kiến ​​như this one trên trang hướng dẫn sử dụng bind_result().

Hoặc bạn chỉ có thể chỉ định các cột bạn muốn lấy:

$sql_con = new mysqli('db', 'username', 'password', 'database'); 

if($stmt = $sql_con->prepare("SELECT name, countryCode FROM Country WHERE countryCode = ?")) { 

    $stmt->bind_param("s", $country_code); 
    $stmt->execute(); 
    $stmt->bind_result($name, $countryCode); 

    while ($stmt->fetch()) { 
    // Because $name and $countryCode are passed by reference, their value 
    // changes on every iteration to reflect the current row 
    echo "<pre>"; 
    echo "name: $name\n"; 
    echo "countryCode: $countryCode\n"; 
    echo "</pre>"; 
    } 

    $stmt->close(); 

EDIT dựa trên mã mới của bạn, bạn nên làm điều này:

// $date1 will be int(2010), $date2 will be int(1980) because you didn't 
// quote the strings! 
//$date1 = 2012-01-01; 
//$date2 = 2012-01-31; 

// Connect to DB 
$sql_con = new mysqli('db', 'username', 'password', 'database'); 

// Check for connection errors here! 

// The query we want to execute 
$sql = " 
    SELECT eventLogID 
    FROM Country 
    WHERE countryCode = ? 
    AND date BETWEEN ? AND ? 
"; 

// Attempt to prepare the query 
if ($stmt = $sql_con->prepare($sql)) { 

    // Pass the parameters 
    $date1 = '2012-01-01'; 
    $date2 = '2012-01-31'; 
    $stmt->bind_param("sss", $country_code, $date1, $date2); 

    // Execute the query 
    $stmt->execute(); 
    if (!$stmt->errno) { 
    // Handle error here 
    } 

    // Pass a variable to hold the result 
    // Remember you are binding a *column*, not a row 
    $stmt->bind_result($eventLogID); 

    // Loop the results and fetch into an array 
    $logIds = array(); 
    while ($stmt->fetch()) { 
    $logIds[] = $eventLogID; 
    } 

    // Tidy up 
    $stmt->close(); 
    $sql_con->close(); 

    // Do something with the results 
    print_r($logIds); 

} else { 
    // Handle error here 
} 
+0

Cảm ơn câu trả lời của bạn. Tôi đã thực hiện một chút tiến bộ, nhưng kiểm tra chỉnh sửa của tôi cho vấn đề tiếp theo. – Glenncito

+0

@Glenncito Xem chỉnh sửa ở trên – DaveRandom

+0

Tôi cũng đang đấu tranh với điều này, thực hiện một tuyên bố được chuẩn bị lựa chọn sẽ không hoạt động, chính xác những gì bạn đã làm gió lên làm cuối cùng? –

3

Tôi nghĩ bạn phải liên kết với các cột trong bind_results() như

/* prepare statement */ 
if ($stmt = $mysqli->prepare("SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) { 
$stmt->execute(); 

/* bind variables to prepared statement */ 
$stmt->bind_result($col1, $col2); 

/* fetch values */ 
while ($stmt->fetch()) { 
    printf("%s %s\n", $col1, $col2); 
} 

Ở đây $ col1 và $ với phím tắt col2 để Mã và cột Tên của bảng Nước

(Thay vì * trong CHỌN sử dụng các tên cột)

Tham khảo thêm: http://php.net/manual/en/mysqli-stmt.bind-result.php

+0

Cảm ơn bạn đã trả lời. Tôi đã thực hiện một chút tiến bộ, nhưng kiểm tra chỉnh sửa của tôi cho vấn đề tiếp theo. – Glenncito

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