
MySQL 5.5で、mysqlコマンドからSQLを流したときと、PHPから同じSQLを発行したときで結果が違うのです。
どうも日付のパースが関係しているようで、「2014-08-19」と書くとどちらも同じ結果になるのに、
「2014-8-19」と書くとPHPでは1行も返ってこなくなります。
再現例:
==================
CREATE TABLE t (day date NOT NULL) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO t (day) VALUES ('2014-08-19');
SELECT * FROM t WHERE day = '2014-8-19';
+------------+
| day |
+------------+
| 2014-08-19 |
+------------+
1 row in set (0.00 sec)
↑同じSELECTをPHPから発行すると1行も返ってこない。
==================
mysqldとmysqlは5.5.30。
phpinfo()のmysqlのセクションでは
Client API version 5.5.30
と出ています。
show variablesで見るとdate_formatはどちらも%Y-%m-%dになっています。
他にどこを確認すればいいでしょうか?
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
cast してみたら? insert のときは、カラム型に合わせて、かなり柔軟対処してくれるけど
where などでの比較式においては、カラム値の方を文字列変換してから、文字列比較したりすることがあるらしいので(特にdatetime と日付だけの文字列を比較したとき)、今回は文字コードかCOLLATE の関係で、それが発生していると見られます。
その場合、文字列を日付にキャストするといいらしいです。
WHERE day = CAST('2014-8-19' AS DATE)
この日付文字列の所を、プレースホルダーにすれば、ユーザーから日付入力して貰っても、範囲外でもない限りかなり柔軟に、日付対応できます。
参考
http://matsu.teraren.com/blog/2010/07/27/mysql-d …
「MySQLの日付比較:比較対象のカラムは型を意識しなければならない。」
No.2
- 回答日時:
キャラクターコードの問題かどうかはちょっとわからないですが
それで解決できるならいずれにしろキャラクターコードは指定しなくてはいけない
のですから、それで対応するのもありかもしれません
もちろん、SQLの日付の標準形式(YYYY-MM-DD)で書くのが原則ですが。
MySQLの場合、日付の完全チェックがバージョンによって微妙に違うみたいなので
場合によっては、SELECT文を発行する前にSQLモードを明示してみるとよいかも
SET SQL_MODE='ALLOW_INVALID_DATES';
SELECT * FROM t WHERE day = '2014-8-19';
なおmy.cnfやmy.iniなどでグローバルなSQLモード指定もできるようです。
http://dev.mysql.com/doc/refman/5.1/ja/server-sq …
回答ありがとうございます。
アプリがsjisで書かれていてキャラクターコードはsjisでなければいけないので、対応にはならないのです。
SET SQL_MODE='ALLOW_INVALID_DATES';
を発行してもSQLの結果は変わりませんでした。
今のところ、対応方法はYYYY-MM-DDを使うようにアプリを変更するしかない状況です。
No.1
- 回答日時:
>同じSELECTをPHPから発行すると1行も返ってこない。
PHPからどうやって発行しているのでしょうか?
mysql関数、mysqli関数、PDO?
またプリペアドな処理はしていますか?
この回答への補足
ありがとうございます。
PEAR::DB 1.7.13でmysqliを使っています。
PEAR::DBのmysqli.php 400行目でmysqli_queryを呼び出していて、そこで渡しているSQLが変更されていないことを確認しましたし、そのコネクションを使って自分でmysqli_queryを呼ぶとやはり同じ結果になります。
さらに調べたところ、
set names sjis;
を呼ぶと、コマンドラインmysqlでもSQLの結果が変わることが判明しました。
PHPで再現させる最小のコードです。
$link = mysqli_connect('localhost', '*********', '********', '**********');
// ↓sjisとutf8を切り替えると結果が変わる
mysqli_set_charset($link, "sjis");
//mysqli_set_charset($link, "utf8");
$sql = "SELECT * FROM t WHERE day = '2014-8-19'";
$res = mysqli_query($link, $sql);
echo $res->num_rows, "\n";
while ($row = $res->fetch_row()) {
var_dump($row);
}
mysqli_close($link);
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
<SQL>重複しているデータの場合...
-
複数のテーブルから値を合計出...
-
mysqlでunixtimeによる日付範囲...
-
SQLです教えてくださいお願いし...
-
mysqlでクロス集計を取りたいが...
-
SQLローダーCSV取込で、囲み文...
-
テーブルの最後(最新)のレコー...
-
単一グループのグループ関数で...
-
1の行を固定した上でVBAを用い...
-
Oracleで「文字が無効です」の...
-
count関数の値をwhere句で使用...
-
select文の実行結果に空白行を...
-
group byの並び順を変えるだけ...
-
データ
-
PL/SQL内の共通関数の引数にフ...
-
1レコード全てを改行なしで表...
-
トランザクションログを出力せ...
-
引数によってwhere句を切り替え...
-
SQLで曜日のソートを月火水木金...
-
ntext更新時にエラーが出ます
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
<SQL>重複しているデータの場合...
-
複数のテーブルから値を合計出...
-
最新の日付と2番目の日付のデー...
-
【ExcelVBA】入力された日付か...
-
LIKE検索で範囲指定の方法
-
項目以外の文字列は連結できま...
-
日付
-
Mysqlについて、どの程度の処理...
-
SQLで、同じ値が何回連続す...
-
検索を繰り返す?
-
日付
-
mysqlでunixtimeによる日付範囲...
-
MySQLにおける条件/公開日を指...
-
PHPとMYSQLを使用したデータベ...
-
日付検索で0001-01-01 00:00:00...
-
windows7のmysqlで今日の日付か...
-
型変換
-
効率の良いSQL文の書き方を教え...
-
SQLです教えてくださいお願いし...
-
日付や日時を格納する場合の型...
おすすめ情報