1

異なるデータ型を比較す​​る MySQL について質問があります。次のテーブルがあるとします。

CREATE TABLE `test`(  
  `value` VARCHAR(100)
);

次に、いくつかのデータを挿入します。

INSERT INTO test VALUES ('2XV4F2J');
INSERT INTO test VALUES ('123456');

単純な選択クエリを実行すると、次のようになります。

SELECT * FROM test WHERE `value` = 2

私はさまざまなタイプの比較を認識しているため、この場合、ドキュメントに従ってすべてを「フロート」として比較する必要があります。したがって、予想どおり、結果が得られます。

2XV4F2J

ただし、更新クエリを実行しようとすると

UPDATE test SET `value` = 'some other value' WHERE `value` = 2

次のエラー メッセージが表示されます。

Error Code: 1292
Truncated incorrect DOUBLE value: '2XV4F2J'

私が理解していないのは、UPDATE クエリを実行しているときにのみエラーが発生する理由です。SELECT 中にも同じエラーが発生すると予想していました。

4

1 に答える 1

4

データベースのこの特定の動作は、いわゆる「SQL モード」によって処理されます。ほとんどの場合、MySQL セッションには「STRICT_TRANS_TABLES」が設定されています。これは、発行して確認できSELECT @@session.sql_mode;ます: 。以下の出力例を参照してください。

mysql> SELECT @@session.sql_mode;
+--------------------------------------------+
| @@session.sql_mode                         |
+--------------------------------------------+
| STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------+
1 row in set (0.00 sec)

すべてのモードを詳細に説明するのは少し範囲外ですが、簡潔に言うと、STRICT_TRANS_TABLES モードでは DML ステートメントがロールバックされます。これは、データベースの整合性を確保するためです。つまり、「DML の場合、警告はエラーとして扱われます」というように、UPDATES/INSERTS でデータの整合性を破壊することはできません。SELECT ステートメントの場合、データベースの整合性を損なう危険性はありません。したがって、このモードでは、SELECT を実行すると警告が表示されますが、データは一致する値に変換されます。これは、取得したデータの有効性を保証するのはプログラマーの責任であることを意味します。

上記の例に戻るには、セッションの厳密モードをオフにすることができます。set sql_mode='';この後、UPDATE は動作し、例の SELECT と同じ警告が表示されます。

重要:サーバー/セッションの SQL モードをいじる前に、MySQL-Docs: Server SQL Modesの次の部分を注意深く読んで理解してください。これは結果として、あなたとあなたの開発者が何をしているかを非常に詳細に理解していない限り、データベースに一貫性がなくなる可能性があります. 前述のように、データの一貫性を保証するのは完全にあなた次第です。この作業は DBMS に任せることを強くお勧めします。

上記の例を使用したテスト セッションを以下に示します。

mysql> CREATE TABLE `test`(  
    ->   `value` VARCHAR(100)
    -> );
Query OK, 0 rows affected (0.06 sec)

mysql> INSERT INTO test VALUES ('2XV4F2J');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO test VALUES ('123456');
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM test WHERE `value` = 2;
+---------+
| value   |
+---------+
| 2XV4F2J |
+---------+
1 row in set, 1 warning (0.00 sec)

mysql> UPDATE test SET `value` = 'some other value' WHERE `value` = 2;

ERROR 1292 (22007): Truncated incorrect DOUBLE value: '2XV4F2J'

厳密モードを無効にして、更新を行います。

mysql> set sql_mode='';
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE test SET `value` = 'some other value' WHERE `value` = 2;
Query OK, 1 row affected, 1 warning (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 1

mysql> show warnings;
+---------+------+---------------------------------------------+
| Level   | Code | Message                                     |
+---------+------+---------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '2XV4F2J' |
+---------+------+---------------------------------------------+
1 row in set (0.00 sec)

mysql> select * from test;
+------------------+
| value            |
+------------------+
| some other value |
| 123456           |
+------------------+
2 rows in set (0.00 sec)
于 2013-07-26T08:03:57.147 に答える