2017-02-08 10 views
1

私は、条件の混乱に基づいてエントリの数を数えるDBクエリを実行したいと思います。これまで私がこれまで持っていたことは次のとおりです。奇妙なoccurial mySQLエラーコード1271

MySQL Error 
Message: MySQL Query Error 
SQL: SELECT COUNT(distinct p0.placeid) FROM uchome_place p0 INNER JOIN uchome_place_hours ph ON (p0.placeid=ph.placeid AND ph.weekdays=DATE_FORMAT(NOW(), "%w") AND ph.start<=TIME_FORMAT(TIMESTAMPADD(HOUR,2,NOW()), "%H:%i:%s") AND ph.end>=TIME_FORMAT(TIMESTAMPADD(MINUTE,(CASE p0.book_period WHEN 1 THEN 60 WHEN 2 THEN 120 WHEN 6 THEN 30 ELSE 15 END) ,NOW()), "%H:%i:%s")) 
Error: Illegal mix of collations for operation '>=' 
Errno.: 1271 

このメッセージは、PHPを介してこのクエリを使用してmySQLサーバーにフィードしようとしています。しかし、phpMyAdminを使用して同じクエリを使用して同じmySQLサーバーにフィードしようとすると、クエリはエラーなしで実行されますas shown in this linked picture

私はさらにいくつかのテストを行なったし、Illegal mix of collationsが来ることを発見:phpMyAdminの給電クエリが実行可能とみなすことながら、PHP給電クエリがIllegal mix of collationsとみなすことができるどのように正確に

ph.end>=TIME_FORMAT(TIMESTAMPADD(MINUTE,(CASE book_period WHEN 1 THEN 60 WHEN 2 THEN 120 WHEN 6 THEN 30 ELSE 15 END) ,NOW()), "%H:%i:%s") 

ph.end>=TIME_FORMAT(TIMESTAMPADD(MINUTE,(CASE book_period WHEN 1 THEN 60 WHEN 2 THEN 120 WHEN 6 THEN 30 ELSE 15 END) ,NOW()), "%H:%i:%s")のクエリにはphpMyAdminではなくPHPを使用する必要があります。そのため、phpMyAdminではなく、PHPでエラーがどのように発生するのか説明し、解決する方法が必要です。

PS:コードブロック内のクエリは、Tim Biegeleisenの要求に従って既に短縮されています。元のクエリはway longer, as shown in this linked pictureです。

PPS:lbuによって要求された追加の資料を追加しました。しかし、私は彼のポイントが何であるかは分からない。

<?php 
class dbstuff { 
    var $querynum = 0; 
    var $link; 
    var $charset; 
    function connect($dbhost, $dbuser, $dbpw, $dbname = '', $pconnect = 0, $halt = TRUE) { 
     if($pconnect) { 
      if(!$this->link = @mysql_pconnect($dbhost, $dbuser, $dbpw)) { 
       $halt && $this->halt('Can not connect to MySQL server'); 
      } 
     } 
     else 
     { 
      if(!$this->link = @mysql_connect($dbhost, $dbuser, $dbpw, 1)) { 
       $halt && $this->halt('Can not connect to MySQL server'); 
      } 
     } 
     if($this->version() > '4.1') 
     { 
      if($this->charset) { 
       @mysql_query("SET character_set_connection=".$this->charset.", character_set_results=".$this->charset.", character_set_client=binary", $this->link); 
      } 
      if($this->version() > '5.0.1') { 
       @mysql_query("SET sql_mode=''", $this->link); 
      } 
     } 
     if($dbname) { 
      @mysql_select_db($dbname, $this->link); 
     } 
    } 
    function query($sql, $type = '') { 
     $func = ($type=='UNBUFFERED' && function_exists('mysql_unbuffered_query')) ?'mysql_unbuffered_query':'mysql_query'; 
     if(!($query = $func($sql, $this->link)) && $type != 'SILENT') { 
      $this->halt('MySQL Query Error', $sql); 
     } 
     $this->querynum++; 
     return $query; 
    } 
    function error() { 
     return (($this->link) ? mysql_error($this->link) : mysql_error()); 
    } 
    function errno() { 
     return intval(($this->link) ? mysql_errno($this->link) : mysql_errno()); 
    } 
    function fetch_row($query) { 
     $query = mysql_fetch_row($query); 
     return $query; 
    } 
    function version() { 
     return mysql_get_server_info($this->link); 
    } 
    function close() { 
     return mysql_close($this->link); 
    } 
    function halt($message = '', $sql = '') { 
     $dberror = $this->error(); 
     $dberrno = $this->errno(); 
     echo "<div style=\"position:absolute;font-size:11px;font-family:verdana,arial;background:#EBEBEB;padding:0.5em;\"> 
      <b>MySQL Error</b><br> 
      <b>Message</b>: $message<br> 
      <b>SQL</b>: $sql<br> 
      <b>Error</b>: $dberror<br> 
      <b>Errno.</b>: $dberrno<br> 
      </div>"; 
     exit(); 
    } 
} 
error_reporting(7); 
set_magic_quotes_runtime(0); 
$_SGLOBAL=array(); 
if(empty($_SGLOBAL['db'])){ 
    $_SGLOBAL['db']=new dbstuff; 
    $_SGLOBAL['db']->charset='utf8mb4'; 
    $_SGLOBAL['db']->connect('localhost',$username,$password,$dbname); 
} 
$fullsql="SELECT COUNT(distinct p0.placeid) FROM uchome_place p0 INNER JOIN uchome_place_hours ph ON (p0.placeid=ph.placeid AND ph.weekdays=DATE_FORMAT(NOW(), \"%w\") AND ph.start<=TIME_FORMAT(TIMESTAMPADD(HOUR,2,NOW()), \"%H:%i:%s\") AND ph.end>=TIME_FORMAT(TIMESTAMPADD(MINUTE,(CASE book_period WHEN 1 THEN 60 WHEN 2 THEN 120 WHEN 6 THEN 30 ELSE 15 END) ,NOW()), \"%H:%i:%s\"))"; 
$res=$_SGLOBAL['db']->query($fullsql); 
if(false===$res) 
{ 
    $place_list=false; 
} 
else 
{ 
    $row=$_SGLOBAL['db']->fetch_row($res); 
    if(false===$row) 
    { 
     $place_list=''; 
    } 
    else 
    { 
     $place_list=$row[0]; 
    } 
} 
$_SGLOBAL['db']->close(); 
die(json_encode($place_list)); 
?> 
+0

私は実際に問い合わせがとても巨大であるため、あなたの質問を編集してあきらめました。問題の最小例を教えてください。同じエラーが発生したまま、できるだけクエリを短くします。 –

+0

[トラブルシューティング "MySQLの不正な組み合わせの照合"エラー(http://stackoverflow.com/questions/3029321/troubleshooting-illegal-mix-of-collat​​ions-error-in-mysql) – rkosegi

+0

PHPの場所どこで問題が発生しますか? – Ibu

答えて

0

最後に、この問題を自分で解決しました。ヒントのためにrkosegiに感謝します。

特に、私のコードの問題は、自分のDBのcollation_connectionが明示的に定義されていないことでした。 Which means the DB uses its default value, latin1, in the CASE statement's numbers.CASEd〜、book_periodのカラムはutf8_general_ciで照合されるため、PHPで入力されたMySQL文ではエラー1271が発生します。

ソリューションコード:

<?php 
class dbstuff { 
    var $querynum = 0; 
    var $kink; 
    var $charset; 
    function connect($dbhost, $dbuser, $dbpw, $dbname, $halt=true){ 
     if(!$this->kink = @mysqli_connect($dbhost, $dbuser, $dbpw, $dbname)){ 
      $halt && $this->halt('Can not connect to MySQL server'); 
     } 
     if($this->version() > '4.1') 
     { 
      if($this->charset) { 
       @mysqli_query($this->kink,"SET character_set_connection=".$this->charset.",collation_connection=".$this->charset.", character_set_results=".$this->charset.", character_set_client=binary"); 
       #Question's faulty SQL below. Notice the missing collation_connection 
       #mysqli_query($this->kink,"SET character_set_connection=".$this->charset.", character_set_results=".$this->charset.", character_set_client=binary"); 
      } 
      if($this->version() > '5.0.1') { 
       @mysql_query($this->kink,"SET sql_mode=''"); 
      } 
     } 
    } 
...#rest of the code are unchanged 
} 
... 
?>