2016-01-07 14 views
6

Tôi có một hàm (xem dưới) trong PHP, truy vấn cơ sở dữ liệu MySQL. Khi tôi sử dụng các giá trị sau:PHP PDO: Truy vấn SQL không trả về kết quả mong đợi

  • $ map => 1,
  • $ giới hạn => 10,
  • $ từ => 0,
  • $ to => CURRENT_TIMESTAMP

Với câu lệnh SQL:

SELECT user, 
     scoreVal AS score, 
     UNIX_TIMESTAMP(timestamp) AS timestamp 
    FROM Score 
WHERE timestamp >= :from 
    AND timestamp <= :to 
    AND map = :map 
ORDER BY scoreVal DESC, timestamp ASC 
LIMIT :limit 

Trong phpMyAdmin, tôi nhận được ông sau kết quả:

phpMyAdmin result

Tuy nhiên, PHP PDO được trả lại một mảng trống.

nỗ lực của tôi để debug cho đến nay:

  • tôi đã thay thế ông chuẩn bị truy vấn SQL với giá trị tĩnh thay vì placeholders - Trả đúng
  • Cố gắng từng giữ chỗ riêng biệt, thay thế phần còn lại với thử nghiệm giá trị mã hóa cứng - Trả về không có gì
  • Thay vì truyền biến cho trình giữ chỗ, tôi chuyển các hằng số cố định trong phần thực thi (Array()). - Không trả lại gì cả.
  • Tôi đã phát hiện thêm sau khi bật nhật ký truy vấn mySQL, rằng máy khách PHP Kết nối, nhưng sau đó thoát mà không gửi bất kỳ truy vấn nào.

Từ đây, tôi tin rằng đó là vấn đề với người nắm giữ vị trí trong hàm, tuy nhiên tôi không thể tìm thấy lý do tại sao họ không thực hiện được. Điều này có thể xảy ra nhất ở phía PHP, vì không có lỗi nào được MySQL đưa vào tệp lỗi.

Đây là chức năng Tôi đang sử dụng, với các biến được thông qua tại:

  • $ map => 1,
  • $ giới hạn => 10,
  • $ từ => 0,
  • $ để => 0

Chức năng:

/** 
* Gets the highscore list for the map in that timespan 
* @param integer $map Id of map for which to fetch the highscore 
* @param integer $limit Maximum no. of records to fetch 
* @param integer $from Timestamp from when to find rank 
* @param integer $to Timestamp up to when to find rank 
* @return array Array of highscores arranged by rank for the map in the format [{"user"=>$user,"score"=>score,"timestamp" => timestamp}] 
*/ 
function get_highscore_list($map,$limit,$from,$to){ 
    $sql = "SELECT user,scoreVal AS score,UNIX_TIMESTAMP(timestamp) AS timestamp FROM Score WHERE timestamp >= :from AND timestamp <= :to AND map = :map ORDER BY scoreVal DESC, timestamp ASC LIMIT :limit"; 
    if ($to==intval(0)){ 
     $max =1; 
     $sql = str_replace(":to","NOW()",$sql,$max); 
    } 
    try{ 
    $conn = request_connection(); 
    $stmt = $conn->prepare($sql); 
    $stmt->execute(array(':map'=>$map,':from'=>$from,':limit'=>$limit)); 
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC); 
    }catch(PDOException $e){ 
     $_POST["exception"]=$e; 
     continue; 
    } 
    return $result; 
} 

CHỈNH SỬA


Format của bảng MySQL:

MySQL table format


Tôi đã thử outputting $ conn-> errorInfo() ;, tuy nhiên như không có lỗi được ném, Tôi được trả lại một mảng giá trị: [00000, null, null]


Hàm request_connection chỉ trả về kết quả của hàm này và nó đang làm việc cho tất cả các câu lệnh khác của tôi.

/** 
* Creates a new PDO connection to the database specified in the configuration file 
* @author Ignacy Debicki 
* @return PDO A new open PDO connection to the database 
*/ 
function create_connection(){ 
    try { 
     $config = parse_ini_file('caDB.ini'); 
     $conn = new PDO('mysql' . ':host=' . $config['dbHost'] . ';dbname=' . $config['db'],$config['dbPHPUser'], $config['dbPHPPass']); 
     date_default_timezone_set($config['dbTimezone']); 
     return $conn; 
    } catch(PDOException $e){ 
     throw new Exception("Failed to initiate connection",102,$e); 
    } 
} 

Cảm ơn

+0

Loại dữ liệu của cột 'dấu thời gian' là gì? – mimimito

+0

@RodolfoAndrade Xem câu hỏi cập nhật –

+0

Tôi đã xóa câu trả lời cho câu hỏi của bạn. Tôi giả sử rằng bạn đang sử dụng dấu thời gian UNIX ('INT') cho bảng của bạn và không phải là cột dấu thời gian. – helmbert

Trả lời

3

Sau nhiều giờ cố gắng, tôi cuối cùng đã tìm thấy giải pháp của tôi.

Hai báo cáo quan trọng mà tôi đã bỏ lỡ từ việc tạo kết nối của tôi là:

$conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

mà bật báo cáo lỗi (Xem https://stackoverflow.com/a/8776392/2891273).

Khi tôi bật tính năng này, điều này là do việc ghi đè tham số: thành tham số nếu $ bằng 0, số thông số được chuyển trong câu lệnh $conn->execute() không khớp với số lượng tham số trong truy vấn sql.

Giải pháp của tôi là sử dụng $conn->bindValue() cho mỗi thông số thay vào đó, sử dụng câu lệnh if để kiểm tra xem có liên kết với tham số: to hay không. Dưới đây là giải pháp của tôi:

function get_highscore_list($map,$limit,$from,$to){ 
    $sql='SELECT user, scoreVal AS score, UNIX_TIMESTAMP(timestamp) AS timestamp FROM Score WHERE map = :map AND timestamp >= :from AND timestamp <= :to ORDER BY scoreVal DESC, timestamp ASC LIMIT :limit'; 
    if ($to==0){ 
     $sql = str_replace(":to",'CURRENT_TIMESTAMP()',$sql); 
    } 
    $conn = request_connection(); 
    $stmt = $conn->prepare($sql); 
    $stmt->bindValue(':map',$map,PDO::PARAM_INT); 
    $stmt->bindValue(':from',$from,PDO::PARAM_INT); 
    if ($to!=0){ 
     $stmt->bindValue(':to',$to,PDO::PARAM_INT); 
    } 
    $stmt->bindValue(':limit',$limit,PDO::PARAM_INT); 
    $stmt->execute(); 
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC); 
    return $result; 
} 
+0

Vì vậy, Làm điều này tôi phát hiện ra "sql_mode = only_full_group_by" Và Googles CloudSQL không kết hợp tốt. Tôi có thể thay đổi nó trong khách hàng của tôi, nhưng trong mã của tôi, nó vẫn ném lỗi. Chỉ phát hiện ra nhờ những thuộc tính đó. Tạm biệt Legacy mã, thế hệ thứ hai Cloud SQL là quá nghiêm ngặt cho nó. – Ryan

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