Flink SQL:INSERT Statements

本文介绍了Flink SQL中的INSERT语句,包括如何通过TableEnvironment执行单个或多个INSERT语句,如何在SQL CLI中运行INSERT语句,以及INSERT语句的不同用法,如从查询中插入数据、插入值到表中以及一次插入多张表。

INSERT Statement

INSERT statements are used to add rows to a table.
INSERT语句用于向表中添加行。

Run an INSERT statement

Java
Single INSERT statement can be executed through the executeSql() method of the TableEnvironment. The executeSql() method for INSERT statement will submit a Flink job immediately, and return a TableResult instance which associates the submitted job. Multiple INSERT statements can be executed through the addInsertSql() method of the StatementSet which can be created by the TableEnvironment.createStatementSet() method. The addInsertSql() method is a lazy execution, they will be executed only when StatementSet.execute() is invoked.
单个INSERT语句可以通过TableEnvironment的executeSql()方法执行。执行INSERT语句的executeSql()方法将立即提交Flink作业,并返回与提交的作业关联的TableResult实例。可以通过TableEnvironment.createStatementSet()创建的StatementSet的addInsertSql()方法执行多个INSERT语句。addInsertSql()方法是一个延迟执行,它们将仅在调用StatementSet.execute()时执行。

The following examples show how to run a single INSERT statement in TableEnvironment, run multiple INSERT statements in StatementSet.
以下示例演示如何在TableEnvironment中运行单个INSERT语句,在StatementSet中运行多个INSERT。

TableEnvironment tEnv = TableEnvironment.create(...);

// register a source table named "Orders" and a sink table named "RubberOrders"
tEnv.executeSql("CREATE TABLE Orders (`user` BIGINT, product VARCHAR, amount INT) WITH (...)");
tEnv.executeSql("CREATE TABLE RubberOrders(product VARCHAR, amount INT) WITH (...)");

// run a single INSERT query on the registered source table and emit the result to registered sink table
TableResult tableResult1 = tEnv.executeSql(
  "INSERT INTO RubberOrders SELECT product, amount FROM Orders WHERE product LIKE '%Rubber%'");
// get job status through TableResult
System.out.println(tableResult1.getJobClient().get().getJobStatus());

//----------------------------------------------------------------------------
// register another sink table named "GlassOrders" for multiple INSERT queries
tEnv.executeSql("CREATE TABLE GlassOrders(product VARCHAR, amount INT) WITH (...)");

// run multiple INSERT queries on the registered source table and emit the result to registered sink tables
StatementSet stmtSet = tEnv.createStatementSet();
// only single INSERT query can be accepted by `addInsertSql` method
stmtSet.addInsertSql(
  "INSERT INTO RubberOrders SELECT product, amount FROM Orders WHE
<think>我们正在处理用户的问题:Flink error: only single statement supported 解决方法 根据用户描述,错误信息为'only single statement supported',这通常发生在Flink SQL执行时。 结合引用内容,特别是引用[3]中提到了在Flink SQL CLI中使用DDL创建表等操作,我们可以推断用户可能在尝试执行多个SQL语句时遇到了问题。 原因分析: Flink SQL CLI 或通过程序提交SQL时,一次只能执行一条SQL语句。如果用户在一个请求中提交了多条语句(例如,用分号分隔的多个语句),就会触发这个错误。 解决方案: 1. 确保每次只提交一条SQL语句。 2. 如果是在Flink SQL CLI中,可以逐条执行语句,不要一次粘贴多条。 3. 如果通过程序(如Java/Scala)提交,需要将SQL字符串拆分成单条语句再分别执行。 引用[3]中的操作步骤就是逐条执行的,例如: 4.2 对于数据库中的表 products, orders, shipments,使用Flink SQL CLI创建对应的表(这里应该是分别执行三条CREATE TABLE语句) 另外,注意在Flink 1.13及以后版本,Flink SQL支持SET语句和CREATE语句等,但同样要求每次执行一条。 示例: 错误方式(在同一个字符串中包含多条语句): String sql = "CREATE TABLE ...; INSERT INTO ...;"; 正确方式: 拆分成两条,分别执行: String sql1 = "CREATE TABLE ..."; String sql2 = "INSERT INTO ..."; 在Flink SQL CLI中,用户应该逐条输入并执行。 如果用户使用的是Flink SQL Gateway(引用[1]提到),那么同样需要确保每次请求只包含一条语句。 引用[2]提到单元测试不能捕获所有错误,但这里的问题不是代码逻辑错误,而是使用方式问题。 因此,解决方法总结为:将多条SQL语句拆分成单条语句,逐条执行。 相关问题: 1. Flink SQL CLI 如何执行SQL文件? 2. 如何在Java程序中通过Flink Table API执行多条SQL语句? 3. Flink SQL Gateway 如何配置以支持批量提交? 注意:在Flink 1.16版本中,Flink SQL支持了语句集(STATEMENT SET),允许将多个INSERT语句组合在一起执行,但DDL和DML(INSERT)仍然需要分开。对于非INSERT语句,仍然需要单条执行。 如果用户需要在一个作业中执行多个INSERT,可以使用STATEMENT SET,例如: BEGIN STATEMENT SET; INSERT INTO ... SELECT ...; INSERT INTO ... SELECT ...; END; 但是,CREATE TABLE等DDL语句不能包含在STATEMENT SET中。 因此,用户需要根据语句类型分别处理。</think>### Flink SQL 错误 "only single statement supported" 的解决方法 当 Flink SQL 报错 `only single statement supported` 时,表示**当前执行环境只支持单条 SQL 语句**。以下是常见原因和解决方案: --- #### 一、错误原因分析 1. **批量执行限制** 在 Flink SQL CLI 或 JDBC 驱动中,默认**不支持分号分隔的多语句执行**(如 `CREATE TABLE...; INSERT INTO...;`)[^3]。 2. **SQL 客户端模式限制** Flink SQL CLI 的交互模式(非文件模式)一次仅接受单条语句[^3]。 3. **程序调用方式错误** 通过 `TableEnvironment.executeSql()` 方法执行时传入多条语句会导致此错误。 --- #### 二、解决方案 ##### 方法 1:拆分 SQL 语句(推荐) 将多条语句拆分为独立的执行单元: ```java // Java/Scala 示例 TableEnvironment tableEnv = ...; // ✅ 正确:单条执行 tableEnv.executeSql("CREATE TABLE Orders (...)"); tableEnv.executeSql("INSERT INTO Orders SELECT ..."); ``` ##### 方法 2:使用 STATEMENT SET(适用于批量 INSERT) 对多个 `INSERT` 语句使用 `STATEMENT SET` 包装: ```sql -- Flink SQL 示例 BEGIN STATEMENT SET; INSERT INTO TargetTable1 SELECT ... FROM Source1; INSERT INTO TargetTable2 SELECT ... FROM Source2; END; ``` ##### 方法 3:SQL 文件执行模式 在 Flink SQL CLI 中通过文件执行: ```bash # 创建 SQL 文件(每行一条独立语句) echo "CREATE TABLE T1 (...);" > commands.sql echo "INSERT INTO T1 VALUES (1);" >> commands.sql # 通过文件执行 ./bin/sql-client.sh -f commands.sql ``` ##### 方法 4:启用多语句支持(部分环境) 在 Flink SQL CLI 启动时添加参数(需 Flink 1.15+): ```bash ./bin/sql-client.sh -e "SET sql-client.execution.max-queued-statements = 10;" ``` --- #### 三、验证示例 ```sql -- ✅ 单条执行(成功) CREATE TABLE Orders ( id INT, product STRING ) WITH (...); -- ✅ 使用 STATEMENT SET(成功) BEGIN STATEMENT SET; INSERT INTO Orders VALUES (1, 'Phone'); INSERT INTO Orders VALUES (2, 'Laptop'); END; -- ❌ 错误方式(触发 only single statement supported) CREATE TABLE Test (...); INSERT INTO Test VALUES (1); ``` --- #### 四、最佳实践建议 1. **开发阶段**:使用 `EXPLAIN` 验证单条语句语法 ```sql EXPLAIN INSERT INTO Orders SELECT ...; ``` 2. **流水线管理**:通过 CI/CD 工具(如 Jenkins)拆分 SQL 执行步骤 3. **监控**:在 Flink Web UI 的 **JobManager Logs** 中检查完整错误堆栈 > **关键提示**:该错误通常出现在 SQL 初始化脚本中(如引用[3]的建表语句),确保按单条语句拆分执行[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值