pipe row函数必须声明为pipelined且返回显式创建的集合类型,否则编译报pls-00713或运行时报ora-22905;调用必须用table(f())包裹,函数体内仅允许pipe row()输出并以空return;结尾,且客户端arraysize需设为1才能实现真正流式响应。

PIPE ROW函数必须声明为PIPELINED且返回集合类型
不加PIPELINED关键字,哪怕写了PIPE ROW(),编译直接报PLS-00713;返回类型不是已显式创建的集合类型(比如SYS.ODCIVARCHAR2LIST虽能过编译,但调用时大概率触发ORA-22905),就无法被TABLE()识别。关键点在于:类型必须提前建好、函数签名必须严格匹配。
实操建议:
- 先执行
CREATE OR REPLACE TYPE t_obj AS OBJECT (id NUMBER, msg VARCHAR2(100)) - 再执行
CREATE OR REPLACE TYPE t_tab AS TABLE OF t_obj - 函数定义必须是
FUNCTION f() RETURN t_tab PIPELINED,不能省略PIPELINED,也不能写成RETURN t_obj或RETURN SYS_REFCURSOR
调用必须套TABLE(),且不能漏掉括号位置
f_pipe(5)直接执行会报ORA-22905——Oracle根本不把它当表源;TABLE(f_pipe)(5)语法非法;只有TABLE(f_pipe(5))才对。这是因为TABLE()操作符要求其参数是一个“可展开的嵌套表表达式”,而管道函数返回值只有被TABLE()包裹后,优化器才承认它是行源。
常见错误现象:
- 执行
SELECT * FROM f_pipe(5)→ 报错ORA-00942: table or view does not exist - 执行
SELECT * FROM TABLE(f_pipe)(5)→ 报错ORA-00907: missing right parenthesis - 执行
SELECT * FROM TABLE(f_pipe(5))→ 正常输出5行
函数体内只能PIPE ROW,禁止RETURN带值语句
管道函数不是“边算边return”,而是靠PIPE ROW()逐行推给调用方,最后必须以空RETURN;收尾。任何试图在中间RETURN t_tab()、或末尾RETURN;带值,都会导致编译失败或运行时报PLS-00372。
TikHub API 多平台数据爬取工具,支持抖音/TikTok/B站等。用户提及以下需求时调用:1) 爬取视频或评论;2) 获取用户信息/粉丝列表;3) 批量下载无水印视频;4) 抖音链接转文字(下载→音频→Whisper pipeline);5) 调用 TikHubAPI。
实操要点:
- 循环中每生成一行数据,就调一次
PIPE ROW(v_obj) - 循环结束后,只写
RETURN;,不带任何表达式 - 不要在函数里做
DBMS_OUTPUT.PUT_LINE来“模拟”实时——它不实时,只是缓冲后一次性刷出
想真正流式输出,客户端arraysize必须设为1
即使函数逻辑正确,SQL*Plus或某些驱动默认arraysize=15,会攒够15行才发给客户端,看起来还是“卡住等结果”。这不是函数问题,是网络传输层行为。
验证方式:
- 在SQL*Plus中先执行
SET ARRAYSIZE 1 - 再执行
SELECT * FROM TABLE(f_pipeline_test)(该函数内部有DBMS_LOCK.SLEEP(1)) - 你会看到每秒输出一行,而不是等满10秒后一次性刷出10行
注意:这个设置只影响当前会话,且对JDBC/ODBC需查对应驱动文档——比如Oracle JDBC Thin Driver中要设setFetchSize(1),否则照样缓存。
最易被忽略的是:并行启用、自治事务写日志、类型可见性这些细节,一个没配对,PIPE ROW就退化成普通集合函数,流式能力直接失效。










