質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

PDOでのマイクロ秒

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,433
退会済みユーザー

退会済みユーザー

すみません、初めてマトモな質問をします。よろしくお願いします。

MySQL、PostgreSQLでマイクロ秒のカラムを作り、INSERTするのは出来るのですが、SELECTしてfetchすると秒単位に切り詰められてしまうことに気づきました。

php.netのPDOのマニュアルをざっと見てみたのですが、該当の記述が見当たりませんでした。

PDOでマイクロ秒を取得することは出来ないんでしょうか?

<?php
    $dsn = "mysql:dbname=test_db;port=3306;host=localhost";
    $hdl = new PDO($dsn, "test_user", "testtest");

    if(!$hdl){ echo "could not connect"; exit; }

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

    $qry = "DROP TABLE `hoges`";
    $stmt = $hdl->prepare($qry . ";");
    $result = $stmt->execute();
    if(!$result){ echo "drop table failed"; exit; }

    $qry = <<< EOL
CREATE TABLE `hoges` (
`idx` INT COLLATE utf8mb4_general_ci NOT NULL DEFAULT 0 COMMENT 'ID', 
`add_at` TIMESTAMP(6) COLLATE utf8mb4_general_ci NOT NULL COMMENT 'add_time', 
PRIMARY KEY `p_hoges`(`idx`)
) ENGINE=InnoDB DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_general_ci COMMENT='hogeテーブル';
EOL;

    $stmt = $hdl->prepare($qry . ";");
    $result = $stmt->execute();
    if(!$result){ echo "create table failed"; exit; }

    $qry = "INSERT INTO `hoges`(idx, add_at) VALUES (1, '2016-03-22 19:38.01.123456')";
    $stmt = $hdl->prepare($qry . ";");
    $result = $stmt->execute();
    if(!$result){ echo "insert failed"; exit; }

    $qry = "SELECT * FROM `hoges` WHERE idx = 1";
    $stmt = $hdl->prepare($qry . ";");
    $result = $stmt->execute();
    if(!$result){ echo "select failed"; exit; }

    $result = $stmt->fetchAll(PDO::FETCH_OBJ);
    print_r($result);

出力結果

Array ( [0] => stdClass Object ( [idx] => 1 [add_at] => 2016-03-22 19:38:01 ) )

追記:

ふと検索したstackoverflowを見ると、

http://stackoverflow.com/questions/22026570/php-how-to-return-datetime6-from-mysql

かなり古い話ですが、PDOのバグだというような内容が…
まだ治っていないということでしょうか…

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

MySQLに関しては、以下が関係しているかも知れません。
https://bugs.php.net/bug.php?id=67122

PDO::ATTR_EMULATE_PREPARES = falseのとき、マイクロ秒以下が切り捨てられてしまうそうです。

PostgreSQLについては、それらしい情報を見つけることはできませんでした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/03/23 20:04

    KiyoshiMotoki様、ありがとうございました。

    かなり前からマイクロ秒が取れないことに気づいていて、時間がとれず検証ができないでいてずっと気にかかっていましたが、おかげですっきりしました。

    複文については「適切にSQLインジェクション対策をおこなえば」というところが私のしていることには少々問題で、SQLインジェクションについて全く知らない人でも、手順通りにコードを書けば脆弱性が生まれない事を目指しています。

    マイクロ秒が欲しかったのは楽観排他用のタイムスタンプの精度を上げたかったからですが、複文の危険性を容認するくらいなら、秒単位の楽観排他の方が良いと考えています。

    キャンセル

  • 2016/03/23 22:02

    lucker様、ていねいなご返信、ありがとうございます。
    お役に立てたなら幸いです。

    CertainN様も、情報の捕捉、ありがとうございます。

    キャンセル

  • 2016/03/25 04:54 編集

    複文のことについては知らなかったので助かりました.こちらに追記しておきます.
    http://qiita.com/mpyw/items/b00b72c5c95aac573b71#%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E3%81%BE%E3%81%A8%E3%82%81

    使い方次第で複文からなるプリペアドステートメントは便利になりますね.パフォーマンスもエミュレーションONのほうがよく,同名のプレースホルダを用いて簡単に複雑なSQLが組めるというメリットもあるので,徳丸さんとは逆で私は特別な事情がない限りはエミュレーションONの方を好んで使っています.

    >> 複文については「適切にSQLインジェクション対策をおこなえば」というところが私のしていることには少々問題で、SQLインジェクションについて全く知らない人でも、手順通りにコードを書けば脆弱性が生まれない事を目指しています。

    「正しくない使い方をする人」の場合はそもそもSQL文をPHPの変数展開で組み立ててしまい,この場合はどうであれ脆弱性は発生してしまいます.「SQLインジェクションが発生してもDROPなど破壊的な命令は実行されない」という気休め程度の保険がつくだけで,例えばブラインドSQLインジェクションでデータの二分探索などは平然と許してしまいます.

    >> 複文の危険性を容認するくらいなら、秒単位の楽観排他の方が良いと考えています

    「データの破壊は止められるが盗難は防げない」程度の気休めのために機能面での制約を増やす必要があるかどうかは疑問です.

    http://dsas.blog.klab.org/archives/52021703.html

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る