通过psql脚本返回值判断Greenplum任务是否执行成功

举报
岳涛 发表于 2026/10/21 15:06:37 2026/10/21
【摘要】 由于psql在执行sql脚本文件的过程中,默认是遇到错误继续执行不停止,所以导致我们无法通过其执行的最终返回值来判断该脚本是否有发生错误。

由于psql在执行sql脚本文件的过程中,默认是遇到错误继续执行不停止,所以导致我们无法通过其执行的最终返回值来判断该脚本是否有发生错误。

背景

由于psql在执行sql脚本文件的过程中,默认是遇到错误继续执行不停止,所以导致我们无法通过其执行的最终返回值来判断该脚本是否有发生错误。

  • 用来测试的SQL文件
[gpadmincloud@mdw-snova-90g4jkrm ~]$ cat test.sql 
DROP TABLE IF EXISTS test_demo;
CREATE TABLE test_demo(name varchar, time timestamp);
INSERT INTO test_timestamp VALUES('test',now);
INSERT INTO test_timestamp VALUES('test',111);
SELECT * FROM test_timestamp;
[gpadmincloud@mdw-snova-90g4jkrm ~]$ 

测试文件的第4条SQL,对time字段写入了一个非法时间戳,所以该条SQL一定会执行出错。

[gpadmincloud@mdw-snova-90g4jkrm ~]$ psql -d dy_test -U dy1 -h 10.0.38.133 -f test.sql
psql:test.sql:1: NOTICE:  table "test_demo" does not exist, skipping
DROP TABLE
psql:test.sql:2: NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Greenplum Database data distribution key for this table.
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
CREATE TABLE
INSERT 0 1
psql:test.sql:4: ERROR:  column "time" is of type timestamp without time zone but expression is of type integer
LINE 1: INSERT INTO test_timestamp VALUES('test',111);
                                                 ^
HINT:  You will need to rewrite or cast the expression.
 name |            time            
------+----------------------------
 test | 2021-03-17 19:00:29.765707
 test | 2021-03-17 19:47:04.543494
(2 rows)

[gpadmincloud@mdw-snova-90g4jkrm ~]$ echo $?
0
[gpadmincloud@mdw-snova-90g4jkrm ~]$ 

经过测试,确实是报错了,但是执行并没有中断,而是继续执行了下去。相应的,最终返回值也是不符合预期的0(true),这样则无法根据最终返回值来判断SQL脚本是否执行成功了。所以,这里我们介绍两个方案来实现该需求。

解决方案

方案一:使用psql -c来代替psql -f

[gpadmincloud@mdw-snova-90g4jkrm ~]$ cat test.sh 
#!/bin/bash

psql -d dy_test -U dy1 -h 10.0.38.133 -c "
DROP TABLE IF EXISTS test_demo;
CREATE TABLE test_demo(name varchar, time timestamp);
INSERT INTO test_timestamp VALUES('test',now);
INSERT INTO test_timestamp VALUES('test',111);
SELECT * FROM test_timestamp;"
[gpadmincloud@mdw-snova-90g4jkrm ~]$ bash test.sh 
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Greenplum Database data distribution key for this table.
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
ERROR:  column "time" is of type timestamp without time zone but expression is of type integer
LINE 5: INSERT INTO test_timestamp VALUES('test',111);
                                                 ^
HINT:  You will need to rewrite or cast the expression.
[gpadmincloud@mdw-snova-90g4jkrm ~]$ echo $?
1
[gpadmincloud@mdw-snova-90g4jkrm ~]$ 

可以看到,psql -c的方式,遇到错误会立刻中断,并返回一个非0(false)的值,可以满足我们通过返回值来判断SQL是否全部执行成功的需求。只是这种方式需要嵌套一层shell,不太优雅,介意慎入。

方案二:使用psql参数来指定执行遇错时中断

[gpadmincloud@mdw-snova-90g4jkrm ~]$ psql -d dy_test -U dy1 -h 10.0.38.133 -v ON_ERROR_STOP=1 -f test.sql
DROP TABLE
psql:test.sql:2: NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'name' as the Greenplum Database data distribution key for this table.
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.
CREATE TABLE
INSERT 0 1
psql:test.sql:4: ERROR:  column "time" is of type timestamp without time zone but expression is of type integer
LINE 1: INSERT INTO test_timestamp VALUES('test',111);
                                                 ^
HINT:  You will need to rewrite or cast the expression.
[gpadmincloud@mdw-snova-90g4jkrm ~]$ echo $?
3
[gpadmincloud@mdw-snova-90g4jkrm ~]$

相对方案一,这种方式就显得更加灵活了,堪称完美。

特别注意

不管是使用方案一还是方案二,如果想确认SQL最终是否执行成功,那么一定要要判断返回值是否为0。因为与其他语言不同的是,bash shell的返回值为0才是成功,非0则是失败。再次注意这里,失败是非0,非0,非0,而不是1,重要的话说三遍。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。