Bash向SQL*Plus脚本传参时参数意外包含后续代码的问题解决咨询
Bash向SQL*Plus脚本传参时参数意外包含后续代码的问题解决咨询
嗨,我来帮你捋清楚这个问题的根源和解决办法!
你遇到的核心问题其实是在PL/SQL的BEGIN-END块里直接用SQL*Plus的@命令执行脚本,这本身就不符合语法规范。@是SQLPlus客户端专属的命令,不属于PL/SQL的语法范畴。当你这么写的时候,SQLPlus会错误地把@bar.sql $foo后面的所有代码(包括@foo.sql $foo、COMMIT;这些)都当成bar.sql的参数传递过去,这就是为什么你会看到异常里说COMMIT被当作参数的原因。
给你两个靠谱的解决方向:
方向一:把SQL*Plus命令和PL/SQL块彻底分开
不要在PL/SQL块里调用外部脚本,先单独用SQL*Plus的@命令执行脚本,再用PL/SQL块处理事务逻辑,示例代码如下:$sqlplusconn << EOF -- 先执行外部脚本,这是SQL*Plus命令,和PL/SQL块分开 @bar.sql $foo @foo.sql $foo -- 单独写PL/SQL块处理事务控制 BEGIN COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; -- 可选,把异常抛出来方便你排查问题 END; / -- 注意PL/SQL块末尾要加/,告诉SQL*Plus执行这个块 [... other stuff] EOF方向二:用SQL*Plus变量避免传递异常
如果你担心Bash变量直接替换带来的问题,可以先在SQL*Plus里定义变量,再引用,这样能更稳妥地传递参数:$sqlplusconn << EOF -- 先定义SQL*Plus内部变量 DEFINE foo_val = $foo; -- 用&引用变量传递给脚本 @bar.sql &foo_val @foo.sql &foo_val BEGIN COMMIT; EXCEPTION WHEN OTHERS THEN ROLLBACK; RAISE; END; / [... other stuff] EOF
另外还要提醒一句:如果你的bar.sql和foo.sql本身已经包含了事务控制语句,记得要和外层的COMMIT/ROLLBACK逻辑做好协调,避免出现事务冲突的问题哦。
备注:内容来源于stack exchange,提问作者Mikkel
相关产品推荐
相关产品推荐

