flink-connector-jdbc自定义的oracle dialect 报这个错误,SQL statement must not contain ? character.有人遇到过吗?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
遇到SQL statement must not contain ? character
这个错误,通常意味着您在使用Flink的JDBC Connector时,尝试为不支持参数化的SQL语句设置了参数。Oracle方言可能对SQL语法有特定要求,特别是当直接执行静态SQL而非预编译语句时。根据您的描述和参考资料,这里提供一个解决思路:
?
占位符),但在设置sink时尝试绑定参数类型,这将导致冲突。?
作为参数占位符可能不被支持。检查SQL模板:确认您的自定义Oracle方言中的SQL模板是否确实需要参数化。如果SQL是静态且不包含变量数据,应直接写入具体字段值或表名,而非使用?
。
修改sink配置:如果SQL语句无需动态参数,移除在JDBCAppendTableSink.builder()
中设置的setParameterTypes
调用,并确保setQuery
中的SQL字符串是完整且无?
占位符的。
定制Dialect:如果Oracle方言确实需要特殊处理,考虑实现自定义的Dialect
类以适应Oracle的特定需求,比如重写如何处理参数化查询的方法。
假设原本错误的代码片段类似于:
val insertIntoCkSql = "INSERT INTO sink_table (name, grade, rate) VALUES (?, ?, ?)"
val sink = JDBCAppendTableSink.builder()
.setDrivername("oracle.jdbc.driver.OracleDriver")
.setDBUrl(oracleJdbcUrl)
.setUsername(oracleUsername)
.setPassword(oraclePassword)
.setQuery(insertIntoCkSql) // 这里的SQL含有?
.setBatchSize(BatchSize)
.setParameterTypes(Types.STRING, Types.LONG, Types.FLOAT) // 移除此行
.build()
调整后,如果SQL不需要参数化:
val insertIntoCkSql = "INSERT INTO sink_table (name, grade, rate) VALUES ('John Doe', 120, 3.5)"
val sink = JDBCAppendTableSink.builder()
.setDrivername("oracle.jdbc.driver.OracleDriver")
.setDBUrl(oracleJdbcUrl)
.setUsername(oracleUsername)
.setPassword(oraclePassword)
.setQuery(insertIntoCkSql) // 直接写入具体值
.setBatchSize(BatchSize)
.build()
或者,如果需要动态但Oracle不支持?
,则需采用其他方式动态构造SQL(注意防止SQL注入风险)。
通过上述调整,应该可以解决因不支持参数化查询而导致的错误。
实时计算Flink版是阿里云提供的全托管Serverless Flink云服务,基于 Apache Flink 构建的企业级、高性能实时大数据处理系统。提供全托管版 Flink 集群和引擎,提高作业开发运维效率。