如何在Bash脚本的sqlplus中让SQL语句末尾的/单独换行?
解决Bash脚本中PL/SQL块末尾/无法单独成行的问题
以下是几种可靠的解决方案,确保/在sqlplus执行时单独占一行:
方法1:使用Bash ANSI-C转义字符串定义变量
利用Bash的$''语法直接嵌入换行符\n,让/单独成行:
SQL_STATEMENT=$'DECLARE V_EXIST NUMBER(1); BEGIN SELECT COUNT(1) INTO V_EXIST FROM USER_DB_LINKS WHERE DB_LINK = \'MY_DBLINK\'; IF V_EXIST = 1 THEN EXECUTE IMMEDIATE \'DROP DATABASE LINK MY_DBLINK\';END IF; END;\n /' sqlplus -s /nolog <<EOF > /logs/sql.log CONNECT db_user/db_password@db_name $SQL_STATEMENT EXIT EOF
$''会将\n解析为实际换行符,变量展开后/会自动出现在下一行,注意内部单引号需要用\'转义。
方法2:用printf构建变量
通过printf的格式化功能明确添加换行,可读性更好:
printf -v SQL_STATEMENT '%s\n /' "DECLARE V_EXIST NUMBER(1); BEGIN SELECT COUNT(1) INTO V_EXIST FROM USER_DB_LINKS WHERE DB_LINK = 'MY_DBLINK'; IF V_EXIST = 1 THEN EXECUTE IMMEDIATE 'DROP DATABASE LINK MY_DBLINK';END IF; END;" sqlplus -s /nolog <<EOF > /logs/sql.log CONNECT db_user/db_password@db_name $SQL_STATEMENT EXIT EOF
printf -v会将格式化后的内容直接赋值给变量,%s替换为PL/SQL语句,后续的\n /确保换行和单独的/。
方法3:直接在Here Document中写入PL/SQL块
如果不需要复用变量,直接把代码写在EOF块里是最稳妥的方式,完全避免变量处理的问题:
sqlplus -s /nolog <<EOF > /logs/sql.log CONNECT db_user/db_password@db_name DECLARE V_EXIST NUMBER(1); BEGIN SELECT COUNT(1) INTO V_EXIST FROM USER_DB_LINKS WHERE DB_LINK = 'MY_DBLINK'; IF V_EXIST = 1 THEN EXECUTE IMMEDIATE 'DROP DATABASE LINK MY_DBLINK';END IF; END; / EXIT EOF
注意事项
- 若之前尝试过直接在变量中手动换行,可能因为脚本编辑时的空格压缩、或者Bash的字段分割规则导致换行丢失,上述方法均能规避这类问题。
- sqlplus要求PL/SQL块结束后的
/必须单独占一行,否则无法正确识别块的结束。
内容的提问来源于stack exchange,提问作者user1508682
相关产品推荐
相关产品推荐

