Mysql insert a field long command line without error, but an error jdbc Analysis

Exception information

exception.ServiceException: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'XXX' at row 1

 problem

See a line code runs alarm, it is obvious Analyzing the content exceeds the length of the field into the set of the table structure. But more surprising is why the test environment has not tested it out yet, is it test and configure different Mysql online environment? Consulted dba, get feedback is consistent.

analysis

It can first be determined that the test environment and is consistent with the online form, thus excluding the length field reasons for the discrepancy.

Then there is doubt whether the test environment configuration results in what will be cut off automatically when inserted?

1, shortcut, first search for the keyword "mysql settings automatically inserted into the long break"

The discovery sql_mode mysql:

 

mysql support sql_mode modes: ANSI, TRADITIONAL, STRICT_ALL_TABLES and STRICT_TRANS_TABLES. 

 

ANSI modes : relaxed mode, to insert data validation, if it does not define the type or length, data type, or to adjust the truncation saved, a warning message warning.

 

TRADITIONAL mode : strict mode, when inserting data into mysql database, strictly checking the data to ensure that incorrect data can not be inserted, reported error error. When applied to things, things will be rolled back.

 

STRICT_TRANS_TABLES mode : strict mode, the strict checking of data, incorrect data can not be inserted, reported error error. Valid only for tables that support transactions.

 

STRICT_ALL_TABLES mode : strict mode, the strict checking of data, incorrect data can not be inserted, reported error error. Valid for all tables.

 

Test the command line insert long field contents, there is indeed a warning, but inserted a success. That is my command line executed by default ANSI mode, so only reported warning

Is jdbc set strict mode code runs?

2, check the source code

First, according to the wrong location

Find the corresponding position

Where's look xopen

    public final static int ER_DATA_TOO_LONG = 1406; //SQLSTATE: 22001 Message: Data too long for column '%s' at row %ld
...
    public static final String SQL_STATE_STRING_DATA_RIGHT_TRUNCATION = "22001";
...
  mysqlToSqlState.put(MysqlErrorNumbers.ER_DATA_TOO_LONG, SQL_STATE_STRING_DATA_RIGHT_TRUNCATION);

Specific source code are not expanded, you can see the basic start mysql ERROR SQLSTATE returned a 1406, then became a translator 22, a misjudgment, after MysqlDataTruncation throw an exception.

Notice that there is ERROR, that is to say the jdbc sql_mode should be strict mode, search, find the following code:

    private void setupServerForTruncationChecks() throws SQLException {
        if (getJdbcCompliantTruncation()) {
            if (versionMeetsMinimum(5, 0, 2)) {
                String currentSqlMode = this.serverVariables.get("sql_mode");

                boolean strictTransTablesIsSet = StringUtils.indexOfIgnoreCase(currentSqlMode, "STRICT_TRANS_TABLES") != -1;

                if (currentSqlMode == null || currentSqlMode.length() == 0 || !strictTransTablesIsSet) {
                    StringBuffer commandBuf = new StringBuffer("SET sql_mode='");

                    if (currentSqlMode != null && currentSqlMode.length() > 0) {
                        commandBuf.append(currentSqlMode);
                        commandBuf.append(",");
                    }

                    commandBuf.append("STRICT_TRANS_TABLES'");

                    execSQL(null, commandBuf.toString(), -1, null, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY, false, this.database, null, false);

                    setJdbcCompliantTruncation(false); // server's handling this for us now
                } else if (strictTransTablesIsSet) {
                    // We didn't set it, but someone did, so we piggy back on it
                    setJdbcCompliantTruncation(false); // server's handling this for us now
                }

            }
        }
    }

You can see, the default setting strict mode, and finally solve the case.

After experiencing this problem, know in advance that there is such a pit, in the future if they can execute the command line, and the jdbc implementation error, you can tells why. In addition the command line can also be set sql_mode , so both will agreement.

set sql_mode='STRICT_TRANS_TABLES';

Validation results:

Guess you like

Origin www.cnblogs.com/naiyou/p/11127736.html