2012-05-15 15 views
1

當插入的數據大於目標列時,mysql將引發錯誤。總而言之,這似乎是一種積極的行爲。如何在單個數據庫事務中允許數據截斷?

但是,我想在一個特定事務期間取消此行爲 - 在此tx中,如果數據太大,我希望截斷髮生。

有沒有辦法來禁用這種行爲,但只有一個事務?下面是如何,這是在JDBC級別the documentation

與連接器/ J 3.1.0,JDBC驅動程序發出警告或 開始拋出如通過JDBC 規範要求,除非連接是DataTruncation異常配置爲不通過 使用屬性jdbcCompliantTruncation並將其設置爲false。

回答

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 

你可以在你的程序解析這個結果,刪除該項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(); 
    } 
} 

可以包裹在一個漂亮的形式,如果一個是這樣的傾向。

+1

謝謝,我編輯了你的答案,包括我最終使用的代碼。 – ripper234