2016-01-07 16 views
6

Mam funkcję (patrz na dole) w PHP, która wysyła zapytania do bazy danych MySQL. Kiedy użyć następujących wartości:PHP PDO: zapytanie SQL nie zwracające oczekiwanego wyniku

  • $ mapę => 1,
  • $ limit => 10,
  • $ z => 0,
  • $ to => CURRENT_TIMESTAMP

z 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 

w phpMyAdmin, mam t on następujący wynik:

phpMyAdmin result

Jednak PHP PDO zostanie zwrócony pustą tablicę.

moje próby debugowania dotąd:

  • Wymieniłem przygotował zapytanie SQL z wartościami statycznymi zamiast zastępcze - Zwraca poprawnie
  • Próbując każdy zastępczy osobno, zastępując resztę z testowanych zakodowane wartości - Nic nie zwraca
  • Zamiast przekazywać zmienne do symboli zastępczych, przekazuję stałe stałe w części execute (Array()). - Nic nie zwraca.
  • Ponadto odkryłem po włączeniu dzienników zapytań mySQL, że klient PHP łączy się, ale następnie kończy pracę bez wysyłania jakichkolwiek zapytań.

W związku z tym uważam, że jest to problem związany z posiadaczami miejsc w ramach funkcji, jednak nie mogłem znaleźć przyczyny, dla której zawiodły. Najprawdopodobniej dzieje się tak po stronie PHP, ponieważ MySQL nie zgłasza błędów do pliku błędu.

Jest to funkcja używam, ze zmiennymi były przekazywane w:

  • $ mapie => 1,
  • $ limit => 10,
  • $ z => 0,
  • $ to => 0

Funkcja:

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

edytuje


Format tabeli MySQL:

MySQL table format


Próbowałem wyprowadzenie $ conn-> ErrorInfo() ;, jednak jako błąd nie jest wyrzucane, Otrzymuję tablicę wartości: [00000, null, null]


Funkcja request_connection zwraca tylko wynik tej funkcji i działa dla wszystkich pozostałych moich instrukcji.

/** 
* 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); 
    } 
} 

Dzięki

+0

Jaki jest typ danych kolumny 'timestamp'? – mimimito

+0

@RodolfoAndrade Zobacz zaktualizowane pytanie –

+0

Usunąłem moją odpowiedź na twoje pytanie. Zakładałem, że używasz znacznika czasu UNIX ('INT') dla twojej tabeli, a nie kolumny' timestamp'. – helmbert

Odpowiedz

3

Po wielu godzinach prób, mam w końcu znalazłem rozwiązanie.

Dwa ważne stwierdzenia, że ​​ominęło się od tworzenia moje połączenie to:

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

która włączyć raportowanie błędów (Patrz https://stackoverflow.com/a/8776392/2891273).

Po włączeniu tego problemu było dość proste złapanie mojego problemu, co było spowodowane nadpisaniem: do parametru, jeśli $ to 0, liczba parametrów przekazanych w instrukcji $conn->execute() była niezgodna z liczbą parametry w zapytaniu sql.

Moim rozwiązaniem było użycie $conn->bindValue() dla każdego parametru zamiast tego, używając instrukcji if, aby sprawdzić, czy powiązać z parametrem: to. Poniżej znajduje się moje rozwiązanie:

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

Robiąc to, dowiedziałem się "sql_mode = only_full_group_by", a Googles CloudSQL nie miesza się dobrze. Mogę to zmienić w moim kliencie, ale w moim kodzie nadal powoduje błąd. Tylko się dowiedział dzięki tym atrybutom. Pożegnanie, kod Legacy, Cloud SQL drugiej generacji jest dla niego zbyt rygorystyczny. – Ryan

Powiązane problemy