当插入的数据大于目标列时,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/