Source: https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/call/call-procedure/ Documentation version: v5.3.2 # 使用 CALL 调用命名过程 本文介绍如何使用`CALL`语句调用[命名过程](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/procedures/)。 内置命名过程和用户定义过程(User-Defined Procedure,简称 UDP)使用相同的`CALL`语法。两者的区别在于过程的提供和管理方式,不在于调用方式。有关内置命名过程的信息,请参见[内置命名过程](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/procedures/built-in/)。 调用命名过程时,需指定过程名称及参数值(若有)。要查看可用的命名过程及其输入参数和返回字段,请参见 [SHOW PROCEDURES](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/data-admin/show/show-procedures/)。 此外,必须在`CALL`语句后加上[最终输出语句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/primitive-result/)来指定返回值,否则会报错。 有关如何调用内联过程,请参见[使用 CALL 调用内联过程](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/call/call-inline-procedure/)。 Note 对非默认 Schema 或其中的对象执行操作时,用户既要通过隐式访问规则或显式`USAGE`授权获得该 Schema 的访问权,也要具备目标操作所需的权限。Schema 访问校验和目标操作所需的权限校验相互独立,满足其中一项不能替代另一项。Schema 访问控制不适用于临时图、内置 Procedure 和内置 Function。更多信息,请参见 [Schema 访问控制](https://dev-docs.yueshu.com.cn/v5.3.2/server-admin/authorization/schema-access-control/)。 ## 前提条件 若要调用 UDP,必须是 UDP 的所有者,或具备在 UDP 上执行`EXECUTE`操作的权限,或具备在当前 Schema 执行`EXECUTE ANY PROCEDURE`操作的权限。更多信息,请参见[角色与权限](https://dev-docs.yueshu.com.cn/v5.3.2/server-admin/authorization/)。 ## 语法[]() 语法图源码 call_procedure_statement ```` call_procedure_statement ::= 'OPTIONAL'? 'CALL' procedure_name '(' argument_list? ')' yield_clause? ```` ## 参数 ### `OPTIONAL` 当使用关键字`OPTIONAL`时,即使命名过程没有找到匹配的结果,查询仍会返回`null`作为结果,并返回其他查询结果。否则,如果命名过程没有找到匹配的结果,查询将不返回结果。 ### `procedure_name` 要调用的命名过程的名称。有关可被调用的命名过程的信息,请参见 [SHOW PROCEDURES](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/data-admin/show/show-procedures/)。 ### `argument_list` 传给命名过程的参数值列表。 注意,字符串类型的参数值必须用一组单引号(`'`)或双引号(`"`)包围。例如,`'arg1'`或`"arg1"`。 有关命名过程接受的参数信息,请参见 [SHOW PROCEDURES](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/data-admin/show/show-procedures/)。 ### `yield_clause` `YIELD`子句用于指定哪些过程输出列可以被后续语句引用,并可以使用`AS`重命名这些列。主要在需要限制后续语句可见的过程输出列,或者需要通过重命名避免列名冲突时使用。如果只需要选择最终输出列,可以省略`YIELD`,直接使用`RETURN`。 更多信息,请参见 [YIELD](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/clauses/yield/) 子句和[最终输出语句](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/primitive-result/)。 ## 常用用法 本节及[更多示例](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/call/call-procedure/#more_examples)中涉及图数据的查询基于[示例数据集](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/overview/example-dataset/)。 以下用法同时适用于内置命名过程和 UDP。示例主要使用内置命名过程,以便直接运行。可以按照以下常见形式调用命名过程,并对过程返回的数据进行选择、筛选和处理。方括号中的内容为可选项: ```` ''' CALL () [YIELD [AS ], ...] [FILTER ] RETURN , ... [GROUP BY ] [ORDER BY ] [LIMIT ] ''' ```` 上述形式不是另一套`CALL`语法。第一行遵循[语法](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/call/call-procedure/#syntax)中定义的`call_procedure_statement`;其余各行是在线性查询中处理过程结果的后续语句。 `YIELD`控制进入后续查询的过程输出列,`RETURN`控制最终返回给用户的列。仅在需要裁剪或重命名中间列时使用`YIELD`;如果不存在列名冲突,并且只需要选择最终输出列,可以直接使用`RETURN`。如果不需要过程的返回值,请使用`FINISH`语句结束查询。 Note - 可以使用`RETURN *`返回所有可用列,但不支持`YIELD *`。 - `YIELD`子句仅接受过程返回的列名及其别名。请在`RETURN`语句中使用表达式、函数和聚合。 - 如果过程返回列与前序语句中的变量同名,必须使用`YIELD AS `为返回列指定不同的别名。 ### 返回全部或指定列 不需要处理中间列时,可以省略`YIELD`子句,直接使用`RETURN`语句选择最终输出列。例如,以下语句仅返回图名称、图所在的 Schema 和图所有者: ```` ''' CALL show_graphs() RETURN name, `schema`, owner ''' ```` 要返回所有列,可以使用: ```` CALL show_graphs() RETURN * ```` 由于`schema`是保留关键字,必须使用反引号(```)包围,以将其表示为列名。 ### 筛选和处理过程结果 可以直接根据过程返回列的值筛选数据行: ```` ''' CALL show_graphs() FILTER name = "ldbc" RETURN name, `schema` ''' ```` 如果需要限制后续语句可引用的过程输出列,或者需要重命名返回列,可以在`FILTER`语句之前使用`YIELD`子句: ```` ''' CALL show_graphs() YIELD name AS graph_name, `schema` AS schema_path FILTER graph_name = "ldbc" RETURN graph_name, schema_path ''' ```` 过程返回的数据还可以参与计算、聚合、排序和分页。例如,以下语句返回最多 20 个在线服务: ```` ''' CALL show_services() FILTER status = "ONLINE" RETURN service_type, host, port ORDER BY service_type, host LIMIT 20 ''' ```` 以下语句计算 Leader 分片数: ```` ''' CALL show_peers() FILTER state = "LEADER" RETURN count(partition_id) AS leader_count GROUP BY () ''' ```` ### 将过程结果传递给其他过程 过程的返回列可以作为后续过程的入参。例如,以下语句查找并终止查询文本中包含指定唯一标识的查询: ```` ''' CALL show_queries() YIELD query_id AS qid, `query` AS query_text FILTER query_text LIKE "%%" CALL kill_query(qid) YIELD query_id AS killed_query_id RETURN killed_query_id ''' ```` Warning 后一个过程会对前面查询产生的每一行执行一次。例如,`FILTER`筛选出 3 个查询时,`kill_query(qid)`会执行 3 次,并终止这 3 个查询。 执行终止、写入或控制操作前,建议先移除后续的过程调用,仅返回筛选结果,确认其中只包含目标对象: ```` ''' CALL show_queries() YIELD query_id AS qid, `query` AS query_text FILTER query_text LIKE "%%" RETURN qid, query_text ''' ```` 确认结果后,再执行包含`CALL kill_query(qid)`的语句。这类操作可能还需要额外权限。 ### 使用前序变量作为过程入参 `CALL`语句可以引用前序语句定义的变量。过程会针对前序绑定表中的每一行执行一次。例如: ```` ''' USE movie MATCH (p:Person) CALL version(p.id > 10) RETURN p.id, version LIMIT 5 ''' ```` 该用法也适用于需要根据每行中的点、边或 ID 执行的图算法过程。如果需要在过程未产生结果时仍保留对应的输入行,请使用`OPTIONAL CALL`。此时,过程返回列的值为`null`。更多信息,请参见[使用 OPTIONAL CALL 调用命名过程](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/dql/call/call-procedure/#optional_call_named_procedure)。 ### 不使用过程返回值 如果仅需要执行管理、写入或控制类过程,不需要返回其结果,可以使用`FINISH`语句结束查询。例如: ```` CALL cancel_balance_data() FINISH ```` ### 在标量子查询中使用过程结果 可以在`VALUE`标量子查询中调用过程,并将返回值用于表达式、条件判断或后续计算。标量子查询必须产生单行单列结果。例如: ```` ''' LET current_version = VALUE { CALL version() RETURN version LIMIT 1 } RETURN current_version ''' ```` ## 更多示例[]() ### 省略可选入参 过程`show_graphs()`接受可选入参`graph_type_name`,用于按图类型筛选结果。省略该入参时,过程返回当前 Schema 中的所有图和临时图。 ```` CALL show_graphs() RETURN * ```` 在上述语句中,过程`show_graphs()`调用时不传入参数值,`RETURN *`语句用于返回所有列。 返回: ```` +-------+------------+-------+-------+-----------------+ | extra | graph_type | name | owner | schema | +-------+------------+-------+-------+-----------------+ | | movie_type | movie | root | /default_schema | +-------+------------+-------+-------+-----------------+ ```` ### 调用入参为字符串的命名过程 过程`stats()`用于提交计算指定图的统计信息的作业。它接受一个输入参数`graph_name`并返回一个输出参数`job_id`。 ```` CALL stats("movie") RETURN * ```` 在上述语句中,过程`stats()`调用时传入字符串类型的参数值`"movie"`。 返回: ```` +--------+ | job_id | +--------+ | 1 | +--------+ ```` ### 调用入参为整数的命名过程 过程`show_job()`用于返回作业的详细信息。它接受一个输入参数`job_id`并返回作业的详细信息。 ```` CALL show_job(1) RETURN * ```` 在上述语句中,过程`show_job()`调用时传入整数类型的参数值`1`。 返回: ```` +-----------------------------+-----------------------------+------------+----------------+---------+ | dispatch_time | end_time | service_id | state | task_id | +-----------------------------+-----------------------------+------------+----------------+---------+ | 2026-09-08T07:56:21.984000Z | 2026-09-08T07:56:22.004000Z | 2 | TASK_SUCCEEDED | 1 | +-----------------------------+-----------------------------+------------+----------------+---------+ ```` ### 调用入参为布尔值的命名过程 过程`version()`用于显示悦数图数据库开发版的版本信息。它接受一个输入参数`verbose`并返回一个输出参数`version`。参数`verbose`为布尔类型,默认值为`false`。 ```` CALL version(true) RETURN * ```` 在上述语句中,过程`version()`调用时传入布尔类型的参数值`true`,也即以详细模式显示悦数图数据库开发版的版本信息。 返回: ```` +-------------------------------------------------------+ | version | +-------------------------------------------------------+ | 5.3.2, Git: 37XX278, Build Time: XXX XX 2025 XX:XX:XX | +-------------------------------------------------------+ ```` ### 使用`YIELD`后计算返回值 ```` CALL version(true) YIELD version RETURN substring(version, 1,5) AS v ```` 在上述语句中,`YIELD`子句用于选择列`version`。`RETURN`语句用于返回列`version`的前`5`个字符,并将其命名`v`。 返回: ```` +-------+ | v | +-------+ | 5.3.2 | +-------+ ```` ### 使用 OPTIONAL CALL 调用命名过程[]() ```` ''' // 创建一个名为 gt_for_optional 图类型 CREATE GRAPH TYPE gt_for_optional AS {} ''' ''' // 使用 OPTIONAL CALL 调用 show_graphs CALL show_graph_types() YIELD graph_type AS gt FILTER WHERE gt = "gt_for_optional" OPTIONAL CALL show_graphs(gt) YIELD `name` as graphName RETURN * ''' ```` 上述语句使用关键字`OPTIONAL`调用命名过程`show_graphs()`获取基于图类型`gt_for_optional`创建的图。因为未基于`gt_for_optional`创建图,所以查询返回`null`,并返回其他查询结果。 返回: ```` +-----------+-----------------+ | graphName | gt | +-----------+-----------------+ | null | gt_for_optional | +-----------+-----------------+ ```` ### 调用入参为空的 UDP ```` ''' // 创建一个名为 test1 的 UDP CREATE PROCEDURE IF NOT EXISTS test1() RETURNS ret INT AS { RETURN 1 } ''' ''' // 调用 test1 CALL test1() RETURN ret ''' ```` 上述语句调用了名为 test1 的 UDP。有关如何创建 UDP,请参见 [CREATE PROCEDURE](https://dev-docs.yueshu.com.cn/v5.3.2/database-gql-reference/procedures/create/)。 ### 调用入参为点类型的 UDP ```` ''' // 创建一个入参为点类型 UDP CREATE OR REPLACE PROCEDURE set_proc_param_node (a NODE) RETURNS r INT { RETURN 1 } ''' ''' // 调用 UDP USE movie { MATCH (v:Movie) LIMIT 1 RETURN v NEXT CALL set_proc_param_node(v) RETURN r } ''' ```` 返回: ```` +---+ | r | +---+ | 1 | +---+ ```` ### 调用入参为边类型的 UDP ```` ''' // 创建一个入参为边类型 UDP CREATE OR REPLACE PROCEDURE set_proc_param_edge(e EDGE) RETURNS r INT { MATCH ()-[e]->(f:Genre) RETURN COUNT(f) AS r } ''' ''' // 调用 UDP USE movie MATCH (v:Movie{id: 100})-[e:WithGenre]->() CALL set_proc_param_edge(e) RETURN r ''' ```` 返回: ```` +---+ | r | +---+ | 1 | | 1 | | 1 | | 1 | | 1 | | 1 | | 1 | | 1 | | 1 | +---+ ```` ### 调用入参为表类型的 UDP ```` ''' // 创建一个入参为表类型 UDP CREATE OR REPLACE PROCEDURE set_proc_param_table(a TABLE) RETURNS r INT { RETURN size(a) AS r } ''' ''' // 调用 UDP TABLE t {id, name} = (1, "a"), (2, "b"), (3, "c") CALL set_proc_param_table(t) RETURN r ''' ```` 返回: ```` +---+ | r | +---+ | 3 | +---+ ````