次の形式を使用して、VARCHAR
列から読み取り、TIME
列にデータを挿入する簡単なプロシージャを実行しています。
_STR_TO_DATE(vTestTime, '%H:%i').
_
エラーが出ます
SQLエラー(1411):関数str_to_dateの不正な日時値:'09:22 '
HeidiSQLクライアントから実行すると、同様のステートメントSELECT STR_TO_DATE("09:22", "%H:%i")
がNULLを返すことがわかりました。
この構文が機能していて、設定を変更したことに気づいていないと思いますが、私が間違ったことを提案できますか?
編集:最近の変更を行ったことを思い出して、同じサーバーにWordpressデータベースをインストールしました。何らかの影響があったのでしょうか?
サーバー上で実行されるものは次のとおりです。
_mysql> select str_to_date("09:22", "%H:%i");
+-------------------------------+
| str_to_date("09:22", "%H:%i") |
+-------------------------------+
| NULL |
+-------------------------------+
1 row in set, 1 warning (0.00 sec)
Warning (Code 1411): Incorrect datetime value: '09:22' for function str_to_date
_
これはバグのように見えます(技術的にはバグではありませんが、回答の終わりにある最初の編集を参照してください)。
MySQL 5.7.20および5.7.21(Centos 7.4が重要な場合)での動作を確認します。
mysql> select str_to_date("09:22", "%H:%i");
+-------------------------------+
| str_to_date("09:22", "%H:%i") |
+-------------------------------+
| NULL |
+-------------------------------+
1 row in set, 1 warning (0.00 sec)
警告はコード1411 Incorrect datetime value: '09:22' for function str_to_date
です。
ANSI_QUOTESが有効になっておらず、単一引用符を使用すると同じ警告が表示されます。
私が ドキュメント を読んで理解していることから、クエリは機能するはずです:
STR_TO_DATE()は、フォーマット文字列に日付と時刻の両方の部分が含まれている場合はDATETIME値を返し、文字列に日付と時刻の部分のみが含まれている場合はDATEまたはTIME値を返します。
このクエリは、日付と時間の部分を含み、機能します。
mysql> SELECT STR_TO_DATE("2017-03-17 09:22","%Y-%m-%d %H:%i");
+--------------------------------------------------+
| STR_TO_DATE("2017-03-17 09:22","%Y-%m-%d %H:%i") |
+--------------------------------------------------+
| 2017-03-17 09:22:00 |
+--------------------------------------------------+
1 row in set (0.00 sec)
MariaDB 10.2.14で元のクエリを実行すると、正しく機能します。
MariaDB [(none)]> select str_to_date("09:22", "%H:%i");
+-------------------------------+
| str_to_date("09:22", "%H:%i") |
+-------------------------------+
| 09:22:00 |
+-------------------------------+
1 row in set (0.00 sec)
EDIT:これは以前にバグとして報告されました、ここを参照してください: https://bugs.mysql.com/bug.php?id = 80064
NO_ZERO_DATEまたはNO_ZERO_IN_DATE SQLモードが有効な場合、ゼロの日付または日付の一部は許可されません。その場合、STR_TO_DATE()はNULLを返し、警告を生成します。
これらのモードは、MySQL 5.7ではデフォルトで有効になっています(MariaDB 10.2では無効です)。したがって、これらをsql_modeシステム変数から削除すると、目的の結果が得られます。
mysql> SET sql_mode='';
mysql> select STR_TO_DATE("09:22", "%H:%i");
+-------------------------------+
| STR_TO_DATE("09:22", "%H:%i") |
+-------------------------------+
| 09:22:00 |
+-------------------------------+
1 row in set (0.00 sec)
EDIT 2:sql_mode
システム変数から誤って役立つ/重要なモードを削除したくないので、理想的には特定のモード、この場合はNO_ZERO_DATEおよびNO_ZERO_IN_DATE。これは次の方法で行うことができます:
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'NO_ZERO_DATE', '');
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'NO_ZERO_IN_DATE', '');
(セッションだけでなく、グローバルスコープを変更する場合は、SET GLOBAL sql_mode...
を使用します。)
MySQL構成ファイルでsql_mode
を設定したい場合は、それを「ハードコード」する必要があると思います。つまり、使用しているバージョンのデフォルトモードを確認し、削除します。望ましくないモード、および結果の文字列を追加します。 .cnfファイルの[mysqld]
セクションに:
sql-mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
これはMySQL 5.7では正しいはずです。次のバージョンにアップグレードするときは、設定をもう一度更新する必要があります。
ストアドプロシージャは独自のsql_mode
sで実行されることに注意してください。
MySQLは、ルーチンが作成または変更されたときに有効なsql_modeシステム変数設定を保存し、ルーチンの実行開始時の現在のサーバーSQLモードに関係なく、常にこの設定を有効にしてルーチンを実行します。
ソース: MySQLストアドプロシージャのドキュメント 。
ストアドプロシージャ内でsql_mode
を変更することもできます。