如何在PowerShell调用的SQL*Plus脚本中仅输出DBMS_OUTPUT内容
问题场景
myscript.sql 脚本内容如下:
set serveroutput on set feedback off set heading off set echo off DECLARE CURSOR c1 IS select 2 from dual BEGIN FOR i IN c1 LOOP DBMS_OUTPUT.put_line (i.object_text ); END LOOP; END; / exit;
使用如下PowerShell命令调用脚本:
sqlplus user/pass@database @Dpath\myscript.sql -S | Out-String | echo
当前输出存在以下情况:
- 开头始终打印SQL*Plus版本信息,属于冗余内容
- DBMS_OUTPUT对应的输出行可正常打印,符合预期
- 末尾始终打印
Disconnected .... from Oracle Database的数据库断开连接提示,属于冗余内容
核心需求:过滤所有冗余提示,仅保留DBMS_OUTPUT打印的内容。
解决方案
第一步:修正sqlplus参数位置
你当前命令里的-S(静默模式参数)放在了脚本路径后面,SQL*Plus不会识别该位置的参数——所有sqlplus启动参数必须放在连接串前,或紧跟连接串之后,放在@脚本路径后的内容会被当做脚本入参处理,不会生效。这是开头版本信息没有被屏蔽的核心原因。
调整参数顺序后的基础命令:
sqlplus -S user/pass@database @Dpath\myscript.sql
-S是sqlplus原生的静默模式参数,生效后会自动屏蔽启动版本横幅、SQL命令提示符等大部分自带输出内容。
第二步:标记边界过滤残留冗余提示
部分版本的sqlplus即使开了静默模式,在管道输出场景下仍可能打印断开连接提示,最稳妥的兼容方案是给业务输出加专属边界标记,只提取标记区间内的内容,100%避免冗余内容泄露,也不会误删业务输出。
- 修改myscript.sql,在所有业务输出逻辑的前后加唯一标记:
set serveroutput on set feedback off set heading off set echo off -- 输出起始标记,使用不会和业务输出冲突的唯一字符串 EXEC DBMS_OUTPUT.put_line('===CUSTOM_OUTPUT_START==='); DECLARE CURSOR c1 IS select 2 as object_text from dual; -- 修正原示例游标字段不匹配的问题 BEGIN FOR i IN c1 LOOP DBMS_OUTPUT.put_line (i.object_text ); END LOOP; END; / -- 输出结束标记 EXEC DBMS_OUTPUT.put_line('===CUSTOM_OUTPUT_END==='); exit; - 调整PowerShell调用命令,通过正则提取两个标记中间的纯业务内容:
$rawResult = sqlplus -S user/pass@database @Dpath\myscript.sql | Out-String $cleanResult = [regex]::Match( $rawResult, '===CUSTOM_OUTPUT_START===\r?\n(.*?)\r?\n===CUSTOM_OUTPUT_END===', [System.Text.RegularExpressions.RegexOptions]::Singleline ).Groups[1].Value echo $cleanResult
注:原示例脚本里的游标查询仅返回常量2,没有查询
object_text字段,直接运行会报PLS-00302字段不存在错误,上面的修正版已经补全了字段别名。
内容的提问来源于stack exchange,提问作者Pierre-olivier Gendraud
相关产品推荐
相关产品推荐

