1. CALL 语句是干什么的?
官方定义非常明确:
CALL statements are used to call a stored procedure which is usually provided to perform data manipulation or administrative tasks.
翻译成一句人话:
CALL 用来调用 Catalog 里已经存在的存储过程,用它完成数据处理或管理任务。
2. 重要限制(必读)
⚠️ 注意
目前
CALL要求被调用的 procedure 必须存在于对应的 catalog 中。如果 procedure 不存在,会抛异常。
你需要查阅具体 catalog 的文档,确认有哪些可用 procedures。
如果你想自己实现 procedure,需要参考 Flink 的 Procedure 相关文档/接口。
这段话等价于两个关键结论:
1)CALL 不是"随便写个名字就能跑" ,它只认 catalog 中注册/提供的 procedure。
2)CALL 能调用哪些东西,取决于你当前正在用的 Catalog(比如内存 catalog、Hive catalog、某些自定义 catalog 等)。
3. 语法速记
sql
CALL [catalog_name.][database_name.]procedure_name (
[ expression [, expression]* ]
)
- procedure 可写全限定名:
catalog.db.procedure - 参数列表可选(有的过程不需要参数)
- 参数是表达式(expression),可传常量、函数结果等(具体能传什么由过程签名决定)
4. Java 中怎么执行 CALL?(executeSql 立即调用并返回 TableResult)
在 Java 里,CALL 通过 TableEnvironment.executeSql() 执行:
- 执行时会立刻调用该 procedure
- 返回一个
TableResult,与本次调用关联(可以.print()输出结果)
示例(你提供的官方示例语义):
java
TableEnvironment tEnv = TableEnvironment.create(...);
// 假设当前 catalog 的 system 数据库里已经存在 generate_n 这个 procedure
tEnv.executeSql("CALL `system`.generate_n(4)").print();
这里有两个点值得注意:
- 例子里写的是
system.generate_n(4) :说明它在systemdatabase 中(且属于当前 catalog) generate_n(4)这种很像"生成 N 条数据/结果"的工具型过程(具体行为以实际 catalog 提供为准)
5. 排障与最佳实践:怎么避免"找不到 procedure"的异常?
因为 CALL 的主要坑就是:procedure 不存在。建议形成一个固定排查顺序:
5.1 先确认当前 catalog / database
很多"找不到"的根因是上下文不对:
sql
SHOW CURRENT CATALOG;
SHOW CURRENT DATABASE;
如果需要切库,使用(你前面也在写的):
sql
USE CATALOG xxx;
USE db1;
5.2 再查有哪些 procedures
你前面整理过 SHOW 语句,其中就包含:
sql
SHOW PROCEDURES;
如果你的 catalog 支持 procedures,它能直接把可调用的过程列出来。
如果这里看不到,通常意味着:
- 当前 catalog 不提供 procedures
- 或者 procedure 不在你当前 database 下
- 或者需要查该 catalog 的文档/能力说明
5.3 最后再 CALL
确认存在后再调用:
sql
CALL db_name.proc_name(...);
6. 典型使用场景(工程化思路)
CALL 最大的价值在于:把一些"平台动作"做成标准过程,让 SQL 用户像调用函数一样调用管理能力。例如:
- 数据准备:生成/初始化测试数据、构造样例集
- 管理动作:刷新元数据、触发维护任务、清理某类资源(依赖 catalog 提供)
- 平台化:在 SQL Gateway 场景里,把常用运维能力包装成 procedure 统一入口
关键点:这些场景是否成立,取决于你使用的 catalog 是否提供对应 procedures,或你是否实现了自己的 procedure。
7. 总结
CALL用于调用存储过程(Procedure),常用于数据操作或管理任务- 前提:procedure 必须存在于对应 catalog(不存在会抛异常)
CALL语法支持全限定名:catalog.db.procedure(args...)- Java 中通过
executeSql("CALL ...")立即调用,返回TableResult可.print()输出结果 - 排障建议:先确认 catalog/db → SHOW PROCEDURES → 再 CALL