mysql - 如何在单个数据库事务中允许数据截断?

标签 mysql jpa playframework playframework-1.x

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

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

有没有办法禁用此行为,但仅限于一次交易?这是 the documentation如何做到这一点是在 JDBC 级别:

Starting with Connector/J 3.1.0, the JDBC driver issues warnings or throws DataTruncation exceptions as is required by the JDBC specification unless the connection was configured not to do so by using the property jdbcCompliantTruncation and setting it to false.

最佳答案

行为取决于 MySQL session 变量 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

您可以在您的程序中解析此结果,删除项目 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();
    }
}

如果愿意,可以将它包装成更漂亮的形式。

关于mysql - 如何在单个数据库事务中允许数据截断?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10604159/

相关文章:

hibernate - JPA 条件查询,上课顺序

java - 如何在不是来自 JNDI 的 JPA EntityMangerFactory 上设置数据源

scala - Steam OpenId 和 Play 框架

php - 如何从 codeigniter-query 创建表?

java - 覆盖 Hibernate 注解

mysql - SQL在Rails中查询的位置

postgresql - 如何在保存为 Instant 的 Play-SLICK 中过滤日期?

java - playframework1.2.4中的XSS预防

javascript - Node.js 和 Mysql 的 Promise

mysql - PDO 的 LastInsertID 会破坏 AWS 复制吗?