1

挿入されたデータが宛先列よりも大きい場合、mysql はエラーをスローします。全体として、これはポジティブな行動のようです。

ただし、特定のトランザクションの期間中はこの動作をキャンセルしたいと思います。この tx では、データが大きすぎる場合に切り捨てを行いたいと考えています。

この動作を無効にする方法はありますが、1 つのトランザクションに対してのみですか? JDBC レベルでこれを行う方法のドキュメントを次に示します。

Connector/J 3.1.0 以降、プロパティ jdbcCompliantTruncation を使用してそれを false に設定することによって接続がそうしないように構成されていない限り、JDBC ドライバーは、JDBC 仕様で要求されているように、警告を発行するか DataTruncation 例外をスローします。

4

1 に答える 1

1

動作は、MySQL セッション変数によって異なりますsql_mode。接続中に変数を変更し、後で元の値にリセットできます。私のシステムでは、のデフォルト値sql_modeは次のとおりです。

SELECT @@sql_mode;
-- REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI,NO_AUTO_VALUE_ON_ZERO,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,PAD_CHAR_TO_FULL_LENGTH

プログラムでこの結果を解析し、 item を削除しSTRICT_ALL_TABLES、値を で更新しSET SESSION sql_mode='...'、ステートメントを実行し、トランザクションの最後に変数をリセットできます。

@ ripper234による編集:

この回答の精神で私が書いたコードは次のとおりです。

private static final disableMysqlStrictMode = 
    ((String)Play.configuration.get("db.url")).contains("mysql://");

...

String originalSqlMode = null;
try {
    if (disableMysqlStrictMode) {
        // Strip away mysql's "strict mode" for this transaction - in case one of the columns is truncated, we don't want the entire tx to fail
        // http://stackoverflow.com/a/10606085/11236
        Query query = JPA.em().createNativeQuery("SELECT @@sql_mode;");
        originalSqlMode = (String)query.getSingleResult();
        String newSqlMode = originalSqlMode
            .replace("STRICT_ALL_TABLES", "")
            .replace("STRICT_TRANS_TABLES", "")
            .replace(",,", ",");
        JPA.em().createNativeQuery("SET SESSION sql_mode=?").setParameter(1, newSqlMode).executeUpdate();
    }


    // Save my entity here
    obj.save();


} finally {
    if (originalSqlMode != null) {
        // Restore original sql_mode
        JPA.em().createNativeQuery("SET SESSION sql_mode=?").setParameter(1, originalSqlMode).executeUpdate();
    }
}

その気になれば、もっときれいな形に巻くことができます。

于 2012-05-15T17:45:23.167 に答える