5

My MySQL Server (Windows 2008 Server で PDO を介して PHP で実行) は、列に許可されているよりも長い文字列を挿入すると、エラー コード 1406 (データがフィールドに対して長すぎます) を返します。問題は、厳密モードでない場合、MySQL が通常データを切り捨てることをどこかで読んだことです。my.ini の sql_mode を変更して、起動時にも厳密モードに入らないようにしましたが (現在は "")、それでもエラーが発生してロールバックするため、データが失われます (切り捨てはサイトの望ましい動作)。

コマンドラインに入力し、短い varchar フィールドに長い文字列を挿入すると、データが切り捨てられて保存されますが、そうでないのはサイトです。モードを厳密に戻すと、コマンドラインで切り捨てられませんでした (エラーのみ)。

また、サイト出力をグローバルとセッションの両方の現在のSQLモード(@@GLOBAL.sql_modeと@@SESSION.sql_mode)にしましたが、両方とも「」を出力しましたが、希望どおりに機能しませんでした。

これの原因や変更方法を知っている人はいますか?

私の疑いは、PDO::ATTR_ERRMODE = PDO::ERRMODE_EXCEPTION で有効化された PDO に関係している可能性があるということですが、読んだところ、それについて役立つものは何も見つかりませんでした (これが間違いなく説明だとは思いませんが、問題についてできるだけ多くのことを知ってもらうために、これを公開しているだけです)。

どうもありがとうございました

4

2 に答える 2

4

実際にはそうすべきではありません。悪いデータをデータベースに入れないようにし、挿入する前にスクリプトでサニタイズしてください。

VARCHAR 列の実際の幅がわからない場合、またはスクリプトでハードコーディングしたくない場合は、次のようなクエリを使用してINFORMATION_SCHEMA テーブルにクエリを実行することにより、データベースから読み取ることができます。COLUMNS

SELECT
    column_name,
    data_type,
    character_maximum_length,
    ordinal_position
FROM information_schema.columns
WHERE table_name = 'mytable'

(これを のみに制限したい場合がありますdata_type = 'varchar')。この情報と具体的character_maximum_lengthには、PHP substrを使用して、入力文字列を目的の長さにトリミングできます。

このアプローチの利点は、サーバー構成を変更せず、MySQL だけでなく他のデータベースでも機能することです。

しかし、安全でない方法を主張する場合は、これを実行して一時的に厳格モードを無効にすることができます:

SET sql_mode = '';

その後、MySQL はサイレントに文字列をトリミングする必要があります。詳細はこちらをご覧ください

于 2012-12-28T22:00:42.737 に答える
0

おそらく、mysqlサーバーは「寛容ではない」モード、別名です。伝統的(ほとんどの場合)。mysqlサーバーが許容モードで動作している場合、あなたが読んだことは真実です。長すぎる文字列を挿入しようとすると、それは非常に重要な情報になる可能性があるため、mysqlはエラーを発行します。いくつかの選択肢があります。

1:挿入無視を使用します(これにより、すべてのエラーが警告に変換され、データの切り捨てに進みます)

2:現在のセッションでは、sql_modeを''に設定します

これらのいずれかを使用すると、問題は解決するはずです。

PS:発生しているエラーを読みましたが、サーバーは従来のモードで動作していると思います(したがって、sql_modeを空に設定することをお勧めしたのは間違いありません)。

PS2:my.cnfを変更した後、mysqlサーバーを再起動しましたか?

于 2012-12-28T23:11:09.093 に答える