1

当插入的数据大于目标列时,mysql会抛出错误。总而言之,这似乎是一种积极的行为。

但是,我想在一个特定事务的持续时间内取消此行为 - 在此 tx 中,如果数据太大,我希望发生截断。

有没有办法禁用这种行为,但仅限于一个事务?以下是有关如何在 JDBC 级别执行此操作的文档:

从 Connector/J 3.1.0 开始,JDBC 驱动程序会按照 JDBC 规范的要求发出警告或抛出 DataTruncation 异常,除非通过使用属性 jdbcCompliantTruncation 并将其设置为 false 将连接配置为不这样做。

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 回答