{"record":{"id":"fceead4c31ea29fa","repo":"MyCATApache/Mycat-Server","slug":"multi-statements-is-not-supported-use-single-state","errorCode":null,"errorMessage":"Multi statements is not supported,use single statement instead ","messagePattern":"Multi statements is not supported,use single statement instead ","errorType":"exception","errorClass":"SQLSyntaxErrorException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/route/impl/DruidMycatRouteStrategy.java","lineNumber":137,"sourceCode":"\n\t\t/**\n\t\t * 解析出现问题统一抛SQL语法错误\n\t\t */\n\t\ttry {\n            if (parser instanceof MycatStatementParser || sqlType == ServerParse.LOCK) {\n                /**\n                 * 说明： 1)非mysql数据库因为是jdbc驱动支持多语句，所以无需判断是否为多语句；\n                 * 2)lock类型语句，因为druid自身问题且升级后mycat代码大量编译报错，只能沿用当前逻辑，不判断是否为多语句\n                 */\n                statement = parser.parseStatement();\n            } else {\n                // 因不支持多语句，添加判断是否为多语句\n                List<SQLStatement> statementList = new ArrayList<SQLStatement>();\n\n                /** 最多就解析2条，用于判断是否为批量 **/\n                parser.parseStatementList(statementList, 2);\n                if (statementList.size() > 1) {\n                    throw new SQLSyntaxErrorException(\n                            \"Multi statements is not supported,use single statement instead \");\n                } else {\n                    statement = statementList.get(0);\n                }\n            }\n\n\t\t\tvisitor = new MycatSchemaStatVisitor();\n\t\t} catch (Exception t) {\n\t\t\tLOGGER.error(\"DruidMycatRouteStrategyError\", t);\n\t\t\tthrow new SQLSyntaxErrorException(t);\n\t\t}\n\n\t\t/**\n\t\t * 检验unsupported statement\n\t\t */\n\t\tcheckUnSupportedStatement(statement);\n\n\t\tDruidParser druidParser = DruidParserFactory.create(schema, statement, visitor);","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/route/impl/DruidMycatRouteStrategy.java#L119-L155","documentation":"Mycat's Druid-based router rejects any client SQL that contains more than one statement in a single batch. The parser (druid's parseStatementList with limit 2) is asked to parse up to two statements solely to detect batching; if more than one statement is found, routing cannot proceed because Mycat routes one statement per request. This is a deliberate restriction, not a parse failure of the SQL itself.","triggerScenarios":"Sending a JDBC/MySQL packet containing multiple semicolon-separated statements (e.g. 'insert into t values(1); insert into t values(2);') through Mycat when allowMultiQueries/multiStatementAllow is effectively off; the check lives in routeNormalSqlWithAST0 of DruidMycatRouteStrategy.","commonSituations":"JDBC batch executed with rewriteBatchedStatements or multi-statement connections; migration scripts sent as one string; ORM seeders concatenating DML; clients with allowMultiQueries=true pointed at Mycat.","solutions":["Split the SQL into single statements and execute them one at a time (use JDBC addBatch/executeBatch per statement instead of concatenating with ';').","Remove allowMultiQueries=true from the client JDBC URL when connecting through Mycat.","If you control Mycat config/code, upgrade to a version or patch that supports multi-statement, or place a proxy that splits statements before Mycat.","Route around Mycat for the multi-statement connection (direct DB connection) if batching is essential."],"exampleFix":"// before\nstmt.executeUpdate(\"INSERT INTO t VALUES(1); INSERT INTO t VALUES(2);\");\n// after\ntry (PreparedStatement ps = conn.prepareStatement(\"INSERT INTO t VALUES(?)\")) {\n    ps.setInt(1, 1); ps.addBatch();\n    ps.setInt(1, 2); ps.addBatch();\n    ps.executeBatch();\n}","handlingStrategy":"validation","validationCode":"// Java\nif (sql.trim().indexOf(';', sql.trim().indexOf(';') + 1) != -1) {\n    throw new IllegalArgumentException(\"Multi-statement SQL not supported; split before sending to Mycat\");\n}","typeGuard":"boolean isSingleStatement(String sql) {\n    String s = sql == null ? \"\" : sql.trim();\n    return s.indexOf(';') == -1 || s.indexOf(';') == s.length() - 1;\n}","tryCatchPattern":"try { rrs = route(sql); } catch (SQLSyntaxErrorException e) {\n    if (e.getMessage().contains(\"Multi statements is not supported\")) {\n        for (String part : sql.split(\";\")) { if (!part.isBlank()) route(part); }\n    } else throw e;\n}","preventionTips":["Never concatenate DML with ';' for Mycat connections.","Disable allowMultiQueries=true in JDBC URLs pointed at Mycat.","Use JDBC batching (addBatch/executeBatch) instead of multi-statement strings.","Test migration/seed scripts statement-by-statement."],"tags":["sql","routing","parser"],"backgroundTag":"unsupported-operation","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}