暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

PostgreSQL psql客户端参数 ON_ERROR_STOP 行为原来是这样

原创 柚子身上依 2024-08-27
735

概念描述

ON_ERROR_STOP 
By default, command processing continues after an error. When this variable is set to on, processing will instead stop immediately. In interactive mode, psql will return to the command prompt; otherwise, psql will exit, returning error code 3 to distinguish this case from fatal error conditions, which are reported using error code 1. In either case, any currently running scripts (the top-level script, if any, and any other scripts which it may have in invoked) will be terminated immediately. If the top-level command string contained multiple SQL commands, processing will stop with the current command.

默认情况下,命令处理在出错后继续。当此变量设置为 on 时,处理将立即停止。在交互模式下,psql将返回命令提示符;否则,psql将退出,返回错误代码3,以将此情况与使用错误代码1报告的致命错误情况区分开来。在任何一种情况下,任何当前运行的脚本(顶级脚本,如果有的话,以及它可能调用的任何其他脚本)都将立即终止。如果顶级命令字符串包含多个SQL命令,则处理将以当前命令停止。

测试验证

interactive mode

begin … end 执行多条sql命令

  • 在交互模式下,设置 ON_ERROR_STOP 为 off 或者 on 后,使用begin … end 事务块执行多条sql命令,遇到报错后都是返回到命令提示符( =! ),后续命令执行都报错 ERROR: current transaction is aborted,要求执行rollback来结束报错事务
postgres=# \set ON_ERROR_STOP 'off'
postgres=# begin;
BEGIN
postgres=*# select 1 from;
ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
postgres=!# select 1;
ERROR:  current transaction is aborted, commands ignored until end of transaction block
postgres=!# rollback;
ROLLBACK
postgres=# 
postgres=# \set ON_ERROR_STOP 'on'
postgres=# 
postgres=# begin;
BEGIN
postgres=*# select 1 from;
ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
postgres=!# select 1;
ERROR:  current transaction is aborted, commands ignored until end of transaction block
postgres=!# rollback;
ROLLBACK

begin … end 执行调用sql文件

  • 在交互模式下,设置 ON_ERROR_STOP 为 off,使用begin … end 事务块调用脚本文件,遇到报错后后面sql命令继续执行但都报错(ERROR: current transaction is aborted或者sql本身语法错误),返回到命令提示符 ( =! ) 需要执行rollback结束事务;设置 ON_ERROR_STOP 为 on 后,使用begin … end 事务块用脚本文件,遇到报错后直接跳出脚本回到命令提示符 ( =! ),后续的sql命令不会执行,需要 rollback 来结束事务
postgres=# \! cat 1.sql
select 1 from;
select 1;
select 2 from;
select 2;

postgres=# \set ON_ERROR_STOP 'off'
postgres=# begin;
BEGIN
postgres=*# \i 1.sql
psql:1.sql:1: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
psql:1.sql:2: ERROR:  current transaction is aborted, commands ignored until end of transaction block
psql:1.sql:3: ERROR:  syntax error at or near ";"
LINE 1: select 2 from;
                     ^
psql:1.sql:4: ERROR:  current transaction is aborted, commands ignored until end of transaction block
postgres=!# rollback;
ROLLBACK
postgres=#

postgres=# \set ON_ERROR_STOP 'on'
postgres=# begin;
BEGIN
postgres=*# \i 1.sql
psql:1.sql:1: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
postgres=!# rollback;
ROLLBACK
postgres=#

直接调用sql文件

  • 在交互模式下,设置 ON_ERROR_STOP 为 off,执行报错不影响后续sql命令继续执行;设置 ON_ERROR_STOP 为 on,执行报错直接退出脚本后续sql命令不继续执行
postgres=# \! cat 1.sql
select 1 from;
select 1;
select 2 from;
select 2;

postgres=# \set ON_ERROR_STOP 'off'
postgres=# \i 1.sql
psql:1.sql:1: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
 ?column? 
----------
        1
(1 row)

psql:1.sql:3: ERROR:  syntax error at or near ";"
LINE 1: select 2 from;
                     ^
 ?column? 
----------
        2
(1 row)

postgres=# \set ON_ERROR_STOP 'on'
postgres=# \i 1.sql
psql:1.sql:1: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^

Non-interactive mode

psql -c 执行多行命令

  • 非交互模式下,设置 ON_ERROR_STOP 为 off 或者 on 后,使用 -c 执行多行sql命令报错后直接退出,后面sql命令不会继续执行
[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=off -c "select 1;select 2"
 ?column? 
----------
        1
(1 row)

 ?column? 
----------
        2
(1 row)

[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=off -c "select 1 from;select 2"
ERROR:  syntax error at or near ";"
LINE 1: select 1 from;select 2
                     ^

[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=on -c "select 1;select 2"
 ?column? 
----------
        1
(1 row)

 ?column? 
----------
        2
(1 row)
[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=on -c "select 1 from;select 2"
ERROR:  syntax error at or near ";"
LINE 1: select 1 from;select 2
                     ^

psql -c 执行单行命令

  • 非交互模式下,使用 -c 执行单行命令,存在多个 -c 的情况下,设置 ON_ERROR_STOP=off 遇到报错后不会影响后面 -c 命令的sql正常执行;设置 ON_ERROR_STOP=on 遇到报错后直接退出后面的 -c 命令的sql不会继续执行,并且echo $? 返回值为 1
[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=off -c "select 1 from" -c "select 2"
ERROR:  syntax error at end of input
LINE 1: select 1 from
                     ^
 ?column? 
----------
        2
(1 row)
[postgres@rac01 ~]$ echo $?
0

[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=on -c "select 1 from" -c "select 2"
ERROR:  syntax error at end of input
LINE 1: select 1 from
                     ^
[postgres@rac01 ~]$ echo $?
1

psql 调用脚本

  • 非交互模式下,设置 ON_ERROR_STOP=off 调用脚本报错后会继续执行,并且 echo $? 的返回值为 0;设置 ON_ERROR_STOP=on 调用脚本报错后会直接退出,并且 echo $? 的返回值为 3
[postgres@rac01 ~]$ cat 1.sql
select 1 from;
select 1;
select 2;
select 2 from;

[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=off -f 1.sql
psql:1.sql:1: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
 ?column? 
----------
        1
(1 row)

 ?column? 
----------
        2
(1 row)

psql:1.sql:4: ERROR:  syntax error at or near ";"
LINE 1: select 2 from;
                     ^
[postgres@rac01 ~]$ echo $?
0
[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=on -f 1.sql
psql:1.sql:1: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
[postgres@rac01 ~]$ echo $?
3
  • 脚本中直接添加 \set ON_ERROR_STOP [‘off’|'on] 值与设置 -v ON_ERROR_STOP=[off|on] 可以达到相同的效果
[postgres@rac01 ~]$ psql -f 1.sql
psql:1.sql:2: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
 ?column? 
----------
        1
(1 row)

 ?column? 
----------
        2
(1 row)

psql:1.sql:5: ERROR:  syntax error at or near ";"
LINE 1: select 2 from;
                     ^
[postgres@rac01 ~]$ echo $?
0

[postgres@rac01 ~]$ cat 1.sql
\set ON_ERROR_STOP 'on'
select 1 from;
select 1;
select 2;
select 2 from;
[postgres@rac01 ~]$ psql -f 1.sql
psql:1.sql:2: ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
[postgres@rac01 ~]$ echo $?
3

psql 标准输入调用

  • 非交互模式下,设置 ON_ERROR_STOP=off 标准输入方式执行报错后会继续执行,并且 echo $? 的返回值为 0;设置 ON_ERROR_STOP=on 标准输入方式执行报错后会直接退出,并且 echo $? 的返回值为 3
[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=off<<eof
> select 1 from;
> select 1;
> eof
ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
 ?column? 
----------
        1
(1 row)

[postgres@rac01 ~]$ echo $?
0
[postgres@rac01 ~]$ 
[postgres@rac01 ~]$ psql -v ON_ERROR_STOP=on<<eof 
select 1 from;
select 1;
eof

ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
[postgres@rac01 ~]$ echo $?
3
  • 命令行中直接添加 \set ON_ERROR_STOP [‘off’|'on] 值与设置 -v ON_ERROR_STOP=[off|on] 可以达到相同的效果
[postgres@rac01 ~]$ psql <<eof
\set ON_ERROR_STOP 'off'
select 1 from;
select 1;
eof
ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
 ?column? 
----------
        1
(1 row)

[postgres@rac01 ~]$ echo $?
0

[postgres@rac01 ~]$ psql <<eof
\set ON_ERROR_STOP 'on'
select 1 from;
select 1;
eof
ERROR:  syntax error at or near ";"
LINE 1: select 1 from;
                     ^
[postgres@rac01 ~]$ echo $?
3

知识总结

  • 交互模式下开启事务执行命令,ON_ERROR_STOP 设置为 off 或者 on 行为一致,执行报错后后续sql命令会继续执行但是都会报错,需要 rollback 结束事务
  • 交互模式下开启事务执行脚本,ON_ERROR_STOP 设置为 off 执行报错后后续sql命令会继续执行但是都会报错,需要rollback 结束事务;ON_ERROR_STOP 设置为 on 执行报错后直接退出,后续sql命令不会执行
  • 交互模式下调用sql脚本 ON_ERROR_STOP 设置为 off 执行报错后后续sql命令会继续正常执行;ON_ERROR_STOP 设置为 on 执行报错后直接退出,后续sql命令不会执行
  • 非交互模式下,设置 ON_ERROR_STOP 为 off 或者 on 后,使用 -c 执行多行sql命令报错后直接退出,后面sql命令不会继续执行
  • 非交互模式下,使用 -c 执行单行命令,存在多个 -c 的情况下,设置 ON_ERROR_STOP=off 遇到报错后不会影响后面 -c 命令的sql正常执行;设置 ON_ERROR_STOP=on 遇到报错后直接退出后面的 -c 命令的sql不会继续执行,并且echo $? 返回值为 1
  • 非交互模式下,设置 ON_ERROR_STOP=off 调用脚本报错后会继续执行,并且 echo $? 的返回值为 0;设置 ON_ERROR_STOP=on 调用脚本报错后会直接退出,并且 echo $? 的返回值为 3
  • 非交互模式下,设置 ON_ERROR_STOP=off 标准输入方式执行报错后会继续执行,并且 echo $? 的返回值为 0;设置 ON_ERROR_STOP=on 标准输入方式执行报错后会直接退出,并且 echo $? 的返回值为 3

参考文档

https://www.postgresql.org/docs/17/app-psql.html

最后修改时间:2024-08-28 10:27:09
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论