MyCATApache/Mycat-Server · error · RuntimeException

number of values and columns have to match

Error message

number of values and columns have to match

What it means

InsertData() requires that the number of value expressions in the VALUES clause equals the number of columns listed in the INSERT. When they differ it throws RuntimeException("number of values and columns have to match"). This is a structural validation of the INSERT statement before translation into MongoDB documents.

Solutions

  1. Make the VALUES list contain exactly as many expressions as the column list
  2. Use parameterized/generated SQL builders that pair columns and values together instead of concatenating strings
  3. Count and validate placeholders vs columns before executing (cols.length == values.length)
  4. Catch RuntimeException around executeUpdate and report which SQL statement had the mismatch

Example fix

// before
stmt.executeUpdate("INSERT INTO users (id, name) VALUES (1)");

// after
stmt.executeUpdate("INSERT INTO users (id, name) VALUES (1, 'alice')");
Defensive patterns

Strategy: validation

Validate before calling

SQLInsertStatement ins = (SQLInsertStatement) SQLUtils.parseSingleStatement(sql, dbType);
int cols = ins.getColumns().size();
int vals = ins.getValues().getValues().size();
if (cols != vals) {
    throw new IllegalArgumentException("INSERT column/value mismatch: " + cols + " columns vs " + vals + " values");
}

Try / catch

try {
    return stmt.executeUpdate(sql);
} catch (RuntimeException e) {
    if ("number of values and columns have to match".equals(e.getMessage())) {
        throw new SQLException("INSERT column count != value count: " + sql, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: INSERT INTO t (a,b,c) VALUES (1,2) — column count 3 vs value count 2 — executed via executeUpdate on the MongoDB backend handler.

Common situations: Hand-written INSERT with a missing value, dynamic SQL string concatenation that drops a value, adding a column to the schema without updating all INSERT statements, multi-row VALUES where one row has fewer values.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11). Data as JSON: /api/errors/8747874b90df0326. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/io/mycat/backend/jdbc/mongodb/MongoSQLParser.java:181

        }
        if (statement instanceof SQLDropTableStatement) {
        	return dropTable((SQLDropTableStatement)statement);
        }
        if (statement instanceof SQLDeleteStatement) {
        	return DeleteDate((SQLDeleteStatement)statement);
        }
        if (statement instanceof SQLCreateTableStatement) {
        	return 1;
        }          
		return 1;
		
	}
	private int InsertData(SQLInsertStatement state) {
		if (state.getValues().getValues().size() ==0 ){
			throw new RuntimeException("number of  columns error");
		}		
		if (state.getValues().getValues().size() != state.getColumns().size()){
			throw new RuntimeException("number of values and columns have to match");
		}
		SQLTableSource table=state.getTableSource();
		BasicDBObject[] oList = new BasicDBObject[state.getValuesList().size()];
		int i = 0;
		for(SQLInsertStatement.ValuesClause values : state.getValuesList()){
			int j = 0;
			BasicDBObject o = new BasicDBObject();
			oList[i++] = o ;
			for(SQLExpr col : state.getColumns()) {
				o.put(getFieldName2(col), getExpValue(values.getValues().get(j++)));
			}
		}

		DBCollection coll =this._db.getCollection(table.toString());
		WriteResult result = coll.insert(oList);
		return i; // 这里result.getN 总是返回0 , 所以按插入数据量返回影响行数
	}
	private int UpData(SQLUpdateStatement state) {

View on GitHub (pinned to 65f8d8beb7)